Index: llvm/lib/Analysis/ConstantFolding.cpp =================================================================== --- llvm/lib/Analysis/ConstantFolding.cpp +++ llvm/lib/Analysis/ConstantFolding.cpp @@ -1491,17 +1491,21 @@ case 'l': return Name == "log" || Name == "logf" || Name == "log10" || Name == "log10f"; + case 'n': + return Name == "nearbyint" || Name == "nearbyintf"; case 'p': return Name == "pow" || Name == "powf"; case 'r': - return Name == "round" || Name == "roundf"; + return Name == "rint" || Name == "rintf" || + Name == "round" || Name == "roundf"; case 's': return Name == "sin" || Name == "sinf" || Name == "sinh" || Name == "sinhf" || Name == "sqrt" || Name == "sqrtf"; case 't': return Name == "tan" || Name == "tanf" || - Name == "tanh" || Name == "tanhf"; + Name == "tanh" || Name == "tanhf" || + Name == "trunc" || Name == "truncf"; case '_': // Check for various function names that get used for the math functions // when the header files are preprocessed with the macro @@ -1863,7 +1867,6 @@ break; case LibFunc_log: case LibFunc_logf: - case LibFunc_log_finite: case LibFunc_logf_finite: if (W > 0.0 && TLI->has(Func)) @@ -1877,6 +1880,15 @@ // TODO: What about hosts that lack a C99 library? return ConstantFoldFP(log10, W, Ty); break; + case LibFunc_nearbyint: + case LibFunc_nearbyintf: + case LibFunc_rint: + case LibFunc_rintf: + if (TLI->has(Func)) { + V.roundToIntegral(APFloat::rmNearestTiesToEven); + return ConstantFP::get(Ty->getContext(), V); + } + break; case LibFunc_round: case LibFunc_roundf: if (TLI->has(Func)) { @@ -1911,6 +1923,13 @@ if (TLI->has(Func)) return ConstantFoldFP(tanh, W, Ty); break; + case LibFunc_trunc: + case LibFunc_truncf: + if (TLI->has(Func)) { + V.roundToIntegral(APFloat::rmTowardZero); + return ConstantFP::get(Ty->getContext(), V); + } + break; } return nullptr; } Index: llvm/test/Analysis/ConstantFolding/rint.ll =================================================================== --- /dev/null +++ llvm/test/Analysis/ConstantFolding/rint.ll @@ -0,0 +1,109 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -S -early-cse < %s | FileCheck %s + +declare float @nearbyintf(float) #0 +declare float @llvm.nearbyint.f32(float) #0 +declare double @nearbyint(double) #0 +declare double @llvm.nearbyint.f64(double) #0 +declare float @rintf(float) #0 +declare float @llvm.rint.f32(float) #0 +declare double @rint(double) #0 +declare double @llvm.rint.f64(double) #0 + +define float @constant_fold_rint_f32_01() #0 { +; CHECK-LABEL: @constant_fold_rint_f32_01( +; CHECK-NEXT: ret float 1.000000e+00 +; + %x = call float @nearbyintf(float 1.25) #0 + ret float %x +} + +define float @constant_fold_rint_f32_02() #0 { +; CHECK-LABEL: @constant_fold_rint_f32_02( +; CHECK-NEXT: ret float -1.000000e+00 +; + %x = call float @llvm.nearbyint.f32(float -1.25) #0 + ret float %x +} + +define float @constant_fold_rint_f32_03() #0 { +; CHECK-LABEL: @constant_fold_rint_f32_03( +; CHECK-NEXT: ret float 2.000000e+00 +; + %x = call float @rintf(float 1.5) #0 + ret float %x +} + +define float @constant_fold_rint_f32_04() #0 { +; CHECK-LABEL: @constant_fold_rint_f32_04( +; CHECK-NEXT: ret float -2.000000e+00 +; + %x = call float @llvm.rint.f32(float -1.5) #0 + ret float %x +} + +define float @constant_fold_rint_f32_05() #0 { +; CHECK-LABEL: @constant_fold_rint_f32_05( +; CHECK-NEXT: ret float 3.000000e+00 +; + %x = call float @nearbyintf(float 2.75) #0 + ret float %x +} + +define float @constant_fold_rint_f32_06() #0 { +; CHECK-LABEL: @constant_fold_rint_f32_06( +; CHECK-NEXT: ret float -3.000000e+00 +; + %x = call float @llvm.nearbyint.f32(float -2.75) #0 + ret float %x +} + +define double @constant_fold_rint_f64_01() #0 { +; CHECK-LABEL: @constant_fold_rint_f64_01( +; CHECK-NEXT: ret double 1.000000e+00 +; + %x = call double @rint(double 1.3) #0 + ret double %x +} + +define double @constant_fold_rint_f64_02() #0 { +; CHECK-LABEL: @constant_fold_rint_f64_02( +; CHECK-NEXT: ret double -1.000000e+00 +; + %x = call double @llvm.rint.f64(double -1.3) #0 + ret double %x +} + +define double @constant_fold_rint_f64_03() #0 { +; CHECK-LABEL: @constant_fold_rint_f64_03( +; CHECK-NEXT: ret double 2.000000e+00 +; + %x = call double @nearbyint(double 1.5) #0 + ret double %x +} + +define double @constant_fold_rint_f64_04() #0 { +; CHECK-LABEL: @constant_fold_rint_f64_04( +; CHECK-NEXT: ret double -2.000000e+00 +; + %x = call double @llvm.nearbyint.f64(double -1.5) #0 + ret double %x +} + +define double @constant_fold_rint_f64_05() #0 { +; CHECK-LABEL: @constant_fold_rint_f64_05( +; CHECK-NEXT: ret double 3.000000e+00 +; + %x = call double @rint(double 2.7) #0 + ret double %x +} + +define double @constant_fold_rint_f64_06() #0 { +; CHECK-LABEL: @constant_fold_rint_f64_06( +; CHECK-NEXT: ret double -3.000000e+00 +; + %x = call double @llvm.rint.f64(double -2.7) #0 + ret double %x +} + +attributes #0 = { nounwind readnone } Index: llvm/test/Analysis/ConstantFolding/round.ll =================================================================== --- llvm/test/Analysis/ConstantFolding/round.ll +++ llvm/test/Analysis/ConstantFolding/round.ll @@ -1,12 +1,14 @@ -; RUN: opt -S -instcombine < %s | FileCheck %s +; RUN: opt -S -early-cse < %s | FileCheck %s +declare float @roundf(float) #0 declare float @llvm.round.f32(float) #0 +declare double @round(double) #0 declare double @llvm.round.f64(double) #0 ; CHECK-LABEL: @constant_fold_round_f32_01 ; CHECK-NEXT: ret float 1.000000e+00 define float @constant_fold_round_f32_01() #0 { - %x = call float @llvm.round.f32(float 1.25) #0 + %x = call float @roundf(float 1.25) #0 ret float %x } @@ -20,7 +22,7 @@ ; CHECK-LABEL: @constant_fold_round_f32_03 ; CHECK-NEXT: ret float 2.000000e+00 define float @constant_fold_round_f32_03() #0 { - %x = call float @llvm.round.f32(float 1.5) #0 + %x = call float @roundf(float 1.5) #0 ret float %x } @@ -34,7 +36,7 @@ ; CHECK-LABEL: @constant_fold_round_f32_05 ; CHECK-NEXT: ret float 3.000000e+00 define float @constant_fold_round_f32_05() #0 { - %x = call float @llvm.round.f32(float 2.75) #0 + %x = call float @roundf(float 2.75) #0 ret float %x } @@ -48,7 +50,7 @@ ; CHECK-LABEL: @constant_fold_round_f64_01 ; CHECK-NEXT: ret double 1.000000e+00 define double @constant_fold_round_f64_01() #0 { - %x = call double @llvm.round.f64(double 1.3) #0 + %x = call double @round(double 1.3) #0 ret double %x } @@ -62,7 +64,7 @@ ; CHECK-LABEL: @constant_fold_round_f64_03 ; CHECK-NEXT: ret double 2.000000e+00 define double @constant_fold_round_f64_03() #0 { - %x = call double @llvm.round.f64(double 1.5) #0 + %x = call double @round(double 1.5) #0 ret double %x } @@ -76,7 +78,7 @@ ; CHECK-LABEL: @constant_fold_round_f64_05 ; CHECK-NEXT: ret double 3.000000e+00 define double @constant_fold_round_f64_05() #0 { - %x = call double @llvm.round.f64(double 2.7) #0 + %x = call double @round(double 2.7) #0 ret double %x } Index: llvm/test/Analysis/ConstantFolding/trunc.ll =================================================================== --- /dev/null +++ llvm/test/Analysis/ConstantFolding/trunc.ll @@ -0,0 +1,105 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -S -early-cse < %s | FileCheck %s + +declare float @truncf(float) #0 +declare float @llvm.trunc.f32(float) #0 +declare double @trunc(double) #0 +declare double @llvm.trunc.f64(double) #0 + +define float @constant_fold_trunc_f32_01() #0 { +; CHECK-LABEL: @constant_fold_trunc_f32_01( +; CHECK-NEXT: ret float 1.000000e+00 +; + %x = call float @truncf(float 1.25) #0 + ret float %x +} + +define float @constant_fold_trunc_f32_02() #0 { +; CHECK-LABEL: @constant_fold_trunc_f32_02( +; CHECK-NEXT: ret float -1.000000e+00 +; + %x = call float @llvm.trunc.f32(float -1.25) #0 + ret float %x +} + +define float @constant_fold_trunc_f32_03() #0 { +; CHECK-LABEL: @constant_fold_trunc_f32_03( +; CHECK-NEXT: ret float 1.000000e+00 +; + %x = call float @truncf(float 1.5) #0 + ret float %x +} + +define float @constant_fold_trunc_f32_04() #0 { +; CHECK-LABEL: @constant_fold_trunc_f32_04( +; CHECK-NEXT: ret float -1.000000e+00 +; + %x = call float @llvm.trunc.f32(float -1.5) #0 + ret float %x +} + +define float @constant_fold_trunc_f32_05() #0 { +; CHECK-LABEL: @constant_fold_trunc_f32_05( +; CHECK-NEXT: ret float 2.000000e+00 +; + %x = call float @truncf(float 2.75) #0 + ret float %x +} + +define float @constant_fold_trunc_f32_06() #0 { +; CHECK-LABEL: @constant_fold_trunc_f32_06( +; CHECK-NEXT: ret float -2.000000e+00 +; + %x = call float @llvm.trunc.f32(float -2.75) #0 + ret float %x +} + +define double @constant_fold_trunc_f64_01() #0 { +; CHECK-LABEL: @constant_fold_trunc_f64_01( +; CHECK-NEXT: ret double 1.000000e+00 +; + %x = call double @trunc(double 1.3) #0 + ret double %x +} + +define double @constant_fold_trunc_f64_02() #0 { +; CHECK-LABEL: @constant_fold_trunc_f64_02( +; CHECK-NEXT: ret double -1.000000e+00 +; + %x = call double @llvm.trunc.f64(double -1.3) #0 + ret double %x +} + +define double @constant_fold_trunc_f64_03() #0 { +; CHECK-LABEL: @constant_fold_trunc_f64_03( +; CHECK-NEXT: ret double 1.000000e+00 +; + %x = call double @trunc(double 1.5) #0 + ret double %x +} + +define double @constant_fold_trunc_f64_04() #0 { +; CHECK-LABEL: @constant_fold_trunc_f64_04( +; CHECK-NEXT: ret double -1.000000e+00 +; + %x = call double @llvm.trunc.f64(double -1.5) #0 + ret double %x +} + +define double @constant_fold_trunc_f64_05() #0 { +; CHECK-LABEL: @constant_fold_trunc_f64_05( +; CHECK-NEXT: ret double 2.000000e+00 +; + %x = call double @trunc(double 2.7) #0 + ret double %x +} + +define double @constant_fold_trunc_f64_06() #0 { +; CHECK-LABEL: @constant_fold_trunc_f64_06( +; CHECK-NEXT: ret double -2.000000e+00 +; + %x = call double @llvm.trunc.f64(double -2.7) #0 + ret double %x +} + +attributes #0 = { nounwind readnone }