Skip to content

Commit d4912e8

Browse files
committed
ValueTracking: Add some tests to cover asserts in fcmpImpliesClass
Catch asserts hit after 1adce7d8e47e2438f99f91607760b825e5e3cc37
1 parent 638a839 commit d4912e8

File tree

3 files changed

+209
-0
lines changed

3 files changed

+209
-0
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 3
2+
; RUN: opt -S -passes=early-cse < %s | FileCheck %s
3+
4+
; We can't assume comparisons with 0 are exact class tests with dynamic denormal mode
5+
define double @cannot_be_negative_zero_test_dynamic_denormal_fp_math(double %a) #0 {
6+
; CHECK-LABEL: define double @cannot_be_negative_zero_test_dynamic_denormal_fp_math(
7+
; CHECK-SAME: double [[A:%.*]]) #[[ATTR0:[0-9]+]] {
8+
; CHECK-NEXT: entry:
9+
; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq double [[A]], 0.000000e+00
10+
; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], double 1.000000e+00, double 0.000000e+00
11+
; CHECK-NEXT: store double [[COND]], ptr addrspace(5) null, align 8
12+
; CHECK-NEXT: ret double [[COND]]
13+
;
14+
entry:
15+
%cmp = fcmp oeq double %a, 0.000000e+00
16+
%cond = select i1 %cmp, double 1.000000e+00, double 0.000000e+00
17+
store double %cond, ptr addrspace(5) null, align 8
18+
%load = load double, ptr addrspace(5) null, align 8
19+
%add.i = fadd double %load, 0.000000e+00
20+
ret double %add.i
21+
}
22+
23+
define double @cannot_be_negative_zero_test_dynamic_denormal_fp_math_negzero(double %a) #0 {
24+
; CHECK-LABEL: define double @cannot_be_negative_zero_test_dynamic_denormal_fp_math_negzero(
25+
; CHECK-SAME: double [[A:%.*]]) #[[ATTR0]] {
26+
; CHECK-NEXT: entry:
27+
; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq double [[A]], -0.000000e+00
28+
; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], double 1.000000e+00, double 0.000000e+00
29+
; CHECK-NEXT: store double [[COND]], ptr addrspace(5) null, align 8
30+
; CHECK-NEXT: ret double [[COND]]
31+
;
32+
entry:
33+
%cmp = fcmp oeq double %a, -0.000000e+00
34+
%cond = select i1 %cmp, double 1.000000e+00, double 0.000000e+00
35+
store double %cond, ptr addrspace(5) null, align 8
36+
%load = load double, ptr addrspace(5) null, align 8
37+
%add.i = fadd double %load, 0.000000e+00
38+
ret double %add.i
39+
}
40+
41+
attributes #0 = { "denormal-fp-math"="dynamic,dynamic" }

llvm/test/Transforms/InstSimplify/assume-fcmp-constant-implies-class.ll

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
; classes.
77

88
declare void @llvm.assume(i1 noundef) #0
9+
declare float @llvm.fabs.f32(float) #0
910

1011
; --------------------------------------------------------------------
1112
; Test assume x < -1.0 with compares to 0
@@ -3037,4 +3038,126 @@ define i1 @assume_olt_2__olt_1(float %arg) {
30373038
ret i1 %cmp
30383039
}
30393040

3041+
; --------------------------------------------------------------------
3042+
; Negative infinity
3043+
; --------------------------------------------------------------------
3044+
3045+
define i1 @assume_ogt_neginf_one_neginf(float %arg) {
3046+
; CHECK-LABEL: define i1 @assume_ogt_neginf_one_neginf(
3047+
; CHECK-SAME: float [[ARG:%.*]]) {
3048+
; CHECK-NEXT: [[CMP_OGT_NEGINF:%.*]] = fcmp ogt float [[ARG]], 0xFFF0000000000000
3049+
; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_OGT_NEGINF]])
3050+
; CHECK-NEXT: [[CMP:%.*]] = fcmp one float [[ARG]], 0xFFF0000000000000
3051+
; CHECK-NEXT: ret i1 [[CMP]]
3052+
;
3053+
%cmp.ogt.neginf = fcmp ogt float %arg, 0xFFF0000000000000
3054+
call void @llvm.assume(i1 %cmp.ogt.neginf)
3055+
%cmp = fcmp one float %arg, 0xFFF0000000000000
3056+
ret i1 %cmp
3057+
}
3058+
3059+
define i1 @assume_ogt_neginf_oeq_posinf(float %arg) {
3060+
; CHECK-LABEL: define i1 @assume_ogt_neginf_oeq_posinf(
3061+
; CHECK-SAME: float [[ARG:%.*]]) {
3062+
; CHECK-NEXT: [[CMP_OGT_NEGINF:%.*]] = fcmp ogt float [[ARG]], 0xFFF0000000000000
3063+
; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_OGT_NEGINF]])
3064+
; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq float [[ARG]], 0x7FF0000000000000
3065+
; CHECK-NEXT: ret i1 [[CMP]]
3066+
;
3067+
%cmp.ogt.neginf = fcmp ogt float %arg, 0xFFF0000000000000
3068+
call void @llvm.assume(i1 %cmp.ogt.neginf)
3069+
%cmp = fcmp oeq float %arg, 0x7FF0000000000000
3070+
ret i1 %cmp
3071+
}
3072+
3073+
define i1 @assume_ule_neginf_oeq_neginf(float %arg) {
3074+
; CHECK-LABEL: define i1 @assume_ule_neginf_oeq_neginf(
3075+
; CHECK-SAME: float [[ARG:%.*]]) {
3076+
; CHECK-NEXT: [[CMP_ULE_NEGINF:%.*]] = fcmp ule float [[ARG]], 0xFFF0000000000000
3077+
; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_ULE_NEGINF]])
3078+
; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq float [[ARG]], 0xFFF0000000000000
3079+
; CHECK-NEXT: ret i1 [[CMP]]
3080+
;
3081+
%cmp.ule.neginf = fcmp ule float %arg, 0xFFF0000000000000
3082+
call void @llvm.assume(i1 %cmp.ule.neginf)
3083+
%cmp = fcmp oeq float %arg, 0xFFF0000000000000
3084+
ret i1 %cmp
3085+
}
3086+
3087+
define i1 @assume_ult_neginf_oeq_neginf(float %arg) {
3088+
; CHECK-LABEL: define i1 @assume_ult_neginf_oeq_neginf(
3089+
; CHECK-SAME: float [[ARG:%.*]]) {
3090+
; CHECK-NEXT: [[CMP_ULT_NEGINF:%.*]] = fcmp ult float [[ARG]], 0xFFF0000000000000
3091+
; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_ULT_NEGINF]])
3092+
; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq float [[ARG]], 0xFFF0000000000000
3093+
; CHECK-NEXT: ret i1 [[CMP]]
3094+
;
3095+
%cmp.ult.neginf = fcmp ult float %arg, 0xFFF0000000000000
3096+
call void @llvm.assume(i1 %cmp.ult.neginf)
3097+
%cmp = fcmp oeq float %arg, 0xFFF0000000000000
3098+
ret i1 %cmp
3099+
}
3100+
3101+
define i1 @assume_fabs_ogt_neginf_one_neginf(float %arg) {
3102+
; CHECK-LABEL: define i1 @assume_fabs_ogt_neginf_one_neginf(
3103+
; CHECK-SAME: float [[ARG:%.*]]) {
3104+
; CHECK-NEXT: [[FABS_ARG:%.*]] = call float @llvm.fabs.f32(float [[ARG]])
3105+
; CHECK-NEXT: [[CMP_OGT_NEGINF:%.*]] = fcmp ogt float [[FABS_ARG]], 0xFFF0000000000000
3106+
; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_OGT_NEGINF]])
3107+
; CHECK-NEXT: [[CMP:%.*]] = fcmp one float [[ARG]], 0xFFF0000000000000
3108+
; CHECK-NEXT: ret i1 [[CMP]]
3109+
;
3110+
%fabs.arg = call float @llvm.fabs.f32(float %arg)
3111+
%cmp.ogt.neginf = fcmp ogt float %fabs.arg, 0xFFF0000000000000
3112+
call void @llvm.assume(i1 %cmp.ogt.neginf)
3113+
%cmp = fcmp one float %arg, 0xFFF0000000000000
3114+
ret i1 %cmp
3115+
}
3116+
3117+
define i1 @assume_fabs_ogt_neginf_one_posinf(float %arg) {
3118+
; CHECK-LABEL: define i1 @assume_fabs_ogt_neginf_one_posinf(
3119+
; CHECK-SAME: float [[ARG:%.*]]) {
3120+
; CHECK-NEXT: [[FABS_ARG:%.*]] = call float @llvm.fabs.f32(float [[ARG]])
3121+
; CHECK-NEXT: [[CMP_OGT_NEGINF:%.*]] = fcmp ogt float [[FABS_ARG]], 0xFFF0000000000000
3122+
; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_OGT_NEGINF]])
3123+
; CHECK-NEXT: [[CMP:%.*]] = fcmp one float [[ARG]], 0x7FF0000000000000
3124+
; CHECK-NEXT: ret i1 [[CMP]]
3125+
;
3126+
%fabs.arg = call float @llvm.fabs.f32(float %arg)
3127+
%cmp.ogt.neginf = fcmp ogt float %fabs.arg, 0xFFF0000000000000
3128+
call void @llvm.assume(i1 %cmp.ogt.neginf)
3129+
%cmp = fcmp one float %arg, 0x7FF0000000000000
3130+
ret i1 %cmp
3131+
}
3132+
3133+
define i1 @assume_fabs_ule_neginf_oeq_neginf(float %arg) {
3134+
; CHECK-LABEL: define i1 @assume_fabs_ule_neginf_oeq_neginf(
3135+
; CHECK-SAME: float [[ARG:%.*]]) {
3136+
; CHECK-NEXT: [[FABS_ARG:%.*]] = call float @llvm.fabs.f32(float [[ARG]])
3137+
; CHECK-NEXT: [[CMP_OGT_NEGINF:%.*]] = fcmp ule float [[FABS_ARG]], 0xFFF0000000000000
3138+
; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_OGT_NEGINF]])
3139+
; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq float [[ARG]], 0xFFF0000000000000
3140+
; CHECK-NEXT: ret i1 [[CMP]]
3141+
;
3142+
%fabs.arg = call float @llvm.fabs.f32(float %arg)
3143+
%cmp.ogt.neginf = fcmp ule float %fabs.arg, 0xFFF0000000000000
3144+
call void @llvm.assume(i1 %cmp.ogt.neginf)
3145+
%cmp = fcmp oeq float %arg, 0xFFF0000000000000
3146+
ret i1 %cmp
3147+
}
3148+
3149+
define i1 @assume_oge_neginf_oeq_neginf(float %arg) {
3150+
; CHECK-LABEL: define i1 @assume_oge_neginf_oeq_neginf(
3151+
; CHECK-SAME: float [[ARG:%.*]]) {
3152+
; CHECK-NEXT: [[CMP_OGE_NEGINF:%.*]] = fcmp oge float [[ARG]], 0xFFF0000000000000
3153+
; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_OGE_NEGINF]])
3154+
; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq float [[ARG]], 0xFFF0000000000000
3155+
; CHECK-NEXT: ret i1 [[CMP]]
3156+
;
3157+
%cmp.oge.neginf = fcmp oge float %arg, 0xFFF0000000000000
3158+
call void @llvm.assume(i1 %cmp.oge.neginf)
3159+
%cmp = fcmp oeq float %arg, 0xFFF0000000000000
3160+
ret i1 %cmp
3161+
}
3162+
30403163
attributes #0 = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite) }

llvm/test/Transforms/InstSimplify/known-never-infinity.ll

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1063,6 +1063,51 @@ entry:
10631063
ret i1 %one
10641064
}
10651065

1066+
; This asserted because we didn't handle non-equality comparisons to
1067+
; negative infinity when recognizing is.fpclass-like compares.
1068+
define float @fcmp_ogt_neginf_implies_class_assert(float %arg) {
1069+
; CHECK-LABEL: define float @fcmp_ogt_neginf_implies_class_assert
1070+
; CHECK-SAME: (float [[ARG:%.*]]) {
1071+
; CHECK-NEXT: ret float 0.000000e+00
1072+
;
1073+
%cmp.ogt.neginf = fcmp ogt float %arg, 0xFFF0000000000000
1074+
%select_1_0 = select i1 %cmp.ogt.neginf, float 1.0, float 0.0
1075+
%mul_by_zero = fmul float %select_1_0, 0.0
1076+
ret float %mul_by_zero
1077+
}
1078+
1079+
define float @fcmp_ule_neginf_implies_class_assert(float %arg) {
1080+
; CHECK-LABEL: define float @fcmp_ule_neginf_implies_class_assert
1081+
; CHECK-SAME: (float [[ARG:%.*]]) {
1082+
; CHECK-NEXT: ret float 0.000000e+00
1083+
;
1084+
%cmp.ule.neginf = fcmp ule float %arg, 0xFFF0000000000000
1085+
%select_1_0 = select i1 %cmp.ule.neginf, float 1.0, float 0.0
1086+
%mul_by_zero = fmul float %select_1_0, 0.0
1087+
ret float %mul_by_zero
1088+
}
1089+
1090+
define float @fcmp_oge_neginf_implies_class_assert(float %arg) {
1091+
; CHECK-LABEL: define float @fcmp_oge_neginf_implies_class_assert
1092+
; CHECK-SAME: (float [[ARG:%.*]]) {
1093+
; CHECK-NEXT: ret float 0.000000e+00
1094+
;
1095+
%cmp.oge.neginf = fcmp oge float %arg, 0xFFF0000000000000
1096+
%select_1_0 = select i1 %cmp.oge.neginf, float 1.0, float 0.0
1097+
%mul_by_zero = fmul float %select_1_0, 0.0
1098+
ret float %mul_by_zero
1099+
}
1100+
1101+
define float @fcmp_ult_neginf_implies_class_assert(float %arg) {
1102+
; CHECK-LABEL: define float @fcmp_ult_neginf_implies_class_assert
1103+
; CHECK-SAME: (float [[ARG:%.*]]) {
1104+
; CHECK-NEXT: ret float 0.000000e+00
1105+
;
1106+
%cmp.ult.neginf = fcmp ult float %arg, 0xFFF0000000000000
1107+
%select_1_0 = select i1 %cmp.ult.neginf, float 1.0, float 0.0
1108+
%mul_by_zero = fmul float %select_1_0, 0.0
1109+
ret float %mul_by_zero
1110+
}
10661111

10671112
declare double @llvm.arithmetic.fence.f64(double)
10681113
declare double @llvm.canonicalize.f64(double)

0 commit comments

Comments
 (0)