| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2 | |
| ; RUN: opt < %s -passes=inline -inline-threshold=20 -S | FileCheck %s | |
| ; Make sure there are no crashes when calling computeKnownFPClass with | |
| ; un-inserted cloned instructions. | |
| ; Hit computeKnownFPClass in a context where the denormal mode is | |
| ; queried for the function for an operand not in a parent function. | |
| define i1 @simplify_fcmp_ord_fsub_caller(double nofpclass(zero nan) %i0, double nofpclass(zero nan) %i1) { | |
| ; CHECK-LABEL: define i1 @simplify_fcmp_ord_fsub_caller | |
| ; CHECK-SAME: (double nofpclass(nan zero) [[I0:%.*]], double nofpclass(nan zero) [[I1:%.*]]) { | |
| ; CHECK-NEXT: [[SUB_DOUBLE_SUB_I:%.*]] = fsub double [[I0]], [[I1]] | |
| ; CHECK-NEXT: [[CMP_I:%.*]] = fcmp ord double [[SUB_DOUBLE_SUB_I]], 0.000000e+00 | |
| ; CHECK-NEXT: ret i1 [[CMP_I]] | |
| ; | |
| %call = call i1 @simplify_fcmp_ord_fsub_callee(double %i0, double %i1) | |
| ret i1 %call | |
| } | |
| ; Make sure we hit the denormal query in isKnownNeverLogicalZero | |
| define internal i1 @simplify_fcmp_ord_fsub_callee(double %a, double %b) { | |
| %sub.double.sub = fsub double %a, %b | |
| %cmp = fcmp ord double %sub.double.sub, 0.0 | |
| ret i1 %cmp | |
| } | |
| define i1 @simplify_fcmp_ord_fdiv_caller(double nofpclass(zero nan inf) %i0, double nofpclass(zero nan inf) %i1) { | |
| ; CHECK-LABEL: define i1 @simplify_fcmp_ord_fdiv_caller | |
| ; CHECK-SAME: (double nofpclass(nan inf zero) [[I0:%.*]], double nofpclass(nan inf zero) [[I1:%.*]]) { | |
| ; CHECK-NEXT: [[SUB_DOUBLE_SUB_I:%.*]] = fdiv double [[I0]], [[I1]] | |
| ; CHECK-NEXT: ret i1 true | |
| ; | |
| %call = call i1 @simplify_fcmp_ord_fdiv_callee(double %i0, double %i1) | |
| ret i1 %call | |
| } | |
| ; Make sure we hit the denormal query in isKnownNeverLogicalZero | |
| define internal i1 @simplify_fcmp_ord_fdiv_callee(double %a, double %b) { | |
| %sub.double.sub = fdiv double %a, %b | |
| %cmp = fcmp ord double %sub.double.sub, 0.0 | |
| ret i1 %cmp | |
| } | |
| define i1 @simplify_fcmp_ord_frem_caller(double nofpclass(zero nan inf) %i0, double nofpclass(zero nan inf) %i1) { | |
| ; CHECK-LABEL: define i1 @simplify_fcmp_ord_frem_caller | |
| ; CHECK-SAME: (double nofpclass(nan inf zero) [[I0:%.*]], double nofpclass(nan inf zero) [[I1:%.*]]) { | |
| ; CHECK-NEXT: [[SUB_DOUBLE_SUB_I:%.*]] = frem double [[I0]], [[I1]] | |
| ; CHECK-NEXT: ret i1 true | |
| ; | |
| %call = call i1 @simplify_fcmp_ord_frem_callee(double %i0, double %i1) | |
| ret i1 %call | |
| } | |
| ; Make sure we hit the denormal query in isKnownNeverLogicalZero | |
| define internal i1 @simplify_fcmp_ord_frem_callee(double %a, double %b) { | |
| %sub.double.sub = frem double %a, %b | |
| %cmp = fcmp ord double %sub.double.sub, 0.0 | |
| ret i1 %cmp | |
| } | |
| define i1 @simplify_fcmp_ord_fmul_caller(double nofpclass(zero nan inf) %i0, double nofpclass(zero nan inf) %i1) { | |
| ; CHECK-LABEL: define i1 @simplify_fcmp_ord_fmul_caller | |
| ; CHECK-SAME: (double nofpclass(nan inf zero) [[I0:%.*]], double nofpclass(nan inf zero) [[I1:%.*]]) { | |
| ; CHECK-NEXT: [[SUB_DOUBLE_SUB_I:%.*]] = fmul double [[I0]], [[I1]] | |
| ; CHECK-NEXT: ret i1 true | |
| ; | |
| %call = call i1 @simplify_fcmp_ord_fmul_callee(double %i0, double %i1) | |
| ret i1 %call | |
| } | |
| ; Make sure we hit the denormal query in isKnownNeverLogicalZero | |
| define internal i1 @simplify_fcmp_ord_fmul_callee(double %a, double %b) { | |
| %sub.double.sub = fmul double %a, %b | |
| %cmp = fcmp ord double %sub.double.sub, 0.0 | |
| ret i1 %cmp | |
| } | |
| define i1 @simplify_fcmp_ord_sqrt_caller(double nofpclass(zero nan) %i0) { | |
| ; CHECK-LABEL: define i1 @simplify_fcmp_ord_sqrt_caller | |
| ; CHECK-SAME: (double nofpclass(nan zero) [[I0:%.*]]) { | |
| ; CHECK-NEXT: [[SUB_DOUBLE_SUB_I:%.*]] = call double @llvm.sqrt.f64(double [[I0]]) | |
| ; CHECK-NEXT: [[CMP_I:%.*]] = fcmp ord double [[SUB_DOUBLE_SUB_I]], 0.000000e+00 | |
| ; CHECK-NEXT: ret i1 [[CMP_I]] | |
| ; | |
| %call = call i1 @simplify_fcmp_ord_sqrt_callee(double %i0) | |
| ret i1 %call | |
| } | |
| ; Make sure we hit the denormal query in isKnownNeverLogicalZero | |
| define internal i1 @simplify_fcmp_ord_sqrt_callee(double %a) { | |
| %sub.double.sub = call double @llvm.sqrt.f64(double %a) | |
| %cmp = fcmp ord double %sub.double.sub, 0.0 | |
| ret i1 %cmp | |
| } | |
| declare double @llvm.sqrt.f64(double) | |
| define i1 @simplify_fcmp_ord_canonicalize_caller(double nofpclass(zero nan) %i0) { | |
| ; CHECK-LABEL: define i1 @simplify_fcmp_ord_canonicalize_caller | |
| ; CHECK-SAME: (double nofpclass(nan zero) [[I0:%.*]]) { | |
| ; CHECK-NEXT: [[SUB_DOUBLE_SUB_I:%.*]] = call double @llvm.canonicalize.f64(double [[I0]]) | |
| ; CHECK-NEXT: ret i1 true | |
| ; | |
| %call = call i1 @simplify_fcmp_ord_canonicalize_callee(double %i0) | |
| ret i1 %call | |
| } | |
| ; Make sure we hit the denormal query in isKnownNeverLogicalZero | |
| define internal i1 @simplify_fcmp_ord_canonicalize_callee(double %a) { | |
| %sub.double.sub = call double @llvm.canonicalize.f64(double %a) | |
| %cmp = fcmp ord double %sub.double.sub, 0.0 | |
| ret i1 %cmp | |
| } | |
| declare double @llvm.canonicalize.f64(double) | |
| define i1 @simplify_fcmp_ord_log_caller(double nofpclass(zero nan) %i0) { | |
| ; CHECK-LABEL: define i1 @simplify_fcmp_ord_log_caller | |
| ; CHECK-SAME: (double nofpclass(nan zero) [[I0:%.*]]) { | |
| ; CHECK-NEXT: [[SUB_DOUBLE_SUB_I:%.*]] = call double @llvm.log.f64(double [[I0]]) | |
| ; CHECK-NEXT: [[CMP_I:%.*]] = fcmp ord double [[SUB_DOUBLE_SUB_I]], 0.000000e+00 | |
| ; CHECK-NEXT: ret i1 [[CMP_I]] | |
| ; | |
| %call = call i1 @simplify_fcmp_ord_log_callee(double %i0) | |
| ret i1 %call | |
| } | |
| ; Make sure we hit the denormal query in isKnownNeverLogicalZero | |
| define internal i1 @simplify_fcmp_ord_log_callee(double %a) { | |
| %sub.double.sub = call double @llvm.log.f64(double %a) | |
| %cmp = fcmp ord double %sub.double.sub, 0.0 | |
| ret i1 %cmp | |
| } | |
| declare double @llvm.log.f64(double) | |
| declare float @llvm.maxnum.f32(float, float) #0 | |
| declare <4 x float> @foo() #1 | |
| define void @caller_maxnum() { | |
| ; CHECK-LABEL: define void @caller_maxnum() { | |
| ; CHECK-NEXT: bb: | |
| ; CHECK-NEXT: [[I1_I:%.*]] = call <4 x float> @foo() | |
| ; CHECK-NEXT: [[I2_I:%.*]] = extractelement <4 x float> [[I1_I]], i64 0 | |
| ; CHECK-NEXT: [[I3_I:%.*]] = fmul float [[I2_I]], 0.000000e+00 | |
| ; CHECK-NEXT: [[I4_I:%.*]] = call float @llvm.maxnum.f32(float [[I3_I]], float 0.000000e+00) | |
| ; CHECK-NEXT: [[I5_I:%.*]] = call float @llvm.maxnum.f32(float [[I4_I]], float [[I2_I]]) | |
| ; CHECK-NEXT: ret void | |
| ; | |
| bb: | |
| call void @callee_maxnum() | |
| ret void | |
| } | |
| define internal void @callee_maxnum() { | |
| bb: | |
| %i1 = call <4 x float> @foo() | |
| %i2 = extractelement <4 x float> %i1, i64 0 | |
| %i3 = fmul float %i2, 0.000000e+00 | |
| %i4 = call float @llvm.maxnum.f32(float %i3, float 0.000000e+00) | |
| %i5 = call float @llvm.maxnum.f32(float %i4, float %i2) | |
| %i6 = fcmp olt float %i5, 0.000000e+00 | |
| ret void | |
| } | |
| define i1 @simplify_fcmp_ord_ldexp_caller(double nofpclass(zero inf) %i0) { | |
| ; CHECK-LABEL: define i1 @simplify_fcmp_ord_ldexp_caller | |
| ; CHECK-SAME: (double nofpclass(inf zero) [[I0:%.*]]) { | |
| ; CHECK-NEXT: [[LDEXP_I:%.*]] = call double @llvm.ldexp.f64.i32(double [[I0]], i32 42) | |
| ; CHECK-NEXT: [[CMP_I:%.*]] = fcmp one double [[LDEXP_I]], +inf | |
| ; CHECK-NEXT: ret i1 [[CMP_I]] | |
| ; | |
| %call = call i1 @simplify_fcmp_ord_ldexp_callee(double %i0) | |
| ret i1 %call | |
| } | |
| define internal i1 @simplify_fcmp_ord_ldexp_callee(double %a) { | |
| %ldexp = call double @llvm.ldexp.f64.i32(double %a, i32 42) | |
| %cmp = fcmp one double %ldexp, +inf | |
| ret i1 %cmp | |
| } | |
| declare double @llvm.ldexp.f64.i32(double, i32) | |
| define i1 @simplify_fcmp_ord_frexp_caller(double nofpclass(zero inf) %i0) { | |
| ; CHECK-LABEL: define i1 @simplify_fcmp_ord_frexp_caller | |
| ; CHECK-SAME: (double nofpclass(inf zero) [[I0:%.*]]) { | |
| ; CHECK-NEXT: [[FREXP_I:%.*]] = call { double, i32 } @llvm.frexp.f64.i32(double [[I0]]) | |
| ; CHECK-NEXT: [[FREXP_0_I:%.*]] = extractvalue { double, i32 } [[FREXP_I]], 0 | |
| ; CHECK-NEXT: [[CMP_I:%.*]] = fcmp one double [[FREXP_0_I]], +inf | |
| ; CHECK-NEXT: ret i1 [[CMP_I]] | |
| ; | |
| %call = call i1 @simplify_fcmp_ord_frexp_callee(double %i0) | |
| ret i1 %call | |
| } | |
| define internal i1 @simplify_fcmp_ord_frexp_callee(double %a) { | |
| %frexp = call { double, i32 } @llvm.frexp.f64.i32(double %a) | |
| %frexp.0 = extractvalue { double, i32 } %frexp, 0 | |
| %cmp = fcmp one double %frexp.0, +inf | |
| ret i1 %cmp | |
| } | |
| declare { double, i32 } @llvm.frexp.f64.i32(double) | |
| attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } | |
| attributes #1 = { nocallback nofree nosync nounwind willreturn memory(none) } |