Index: llvm/trunk/lib/Analysis/ConstantFolding.cpp =================================================================== --- llvm/trunk/lib/Analysis/ConstantFolding.cpp +++ llvm/trunk/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 (V > 0.0 && TLI->has(Func)) @@ -1877,6 +1880,15 @@ // TODO: What about hosts that lack a C99 library? return ConstantFoldFP(log10, V, Ty); break; + case LibFunc_nearbyint: + case LibFunc_nearbyintf: + case LibFunc_rint: + case LibFunc_rintf: + if (TLI->has(Func)) { + U.roundToIntegral(APFloat::rmNearestTiesToEven); + return ConstantFP::get(Ty->getContext(), U); + } + break; case LibFunc_round: case LibFunc_roundf: if (TLI->has(Func)) { @@ -1911,6 +1923,13 @@ if (TLI->has(Func)) return ConstantFoldFP(tanh, V, Ty); break; + case LibFunc_trunc: + case LibFunc_truncf: + if (TLI->has(Func)) { + U.roundToIntegral(APFloat::rmTowardZero); + return ConstantFP::get(Ty->getContext(), U); + } + break; } return nullptr; } Index: llvm/trunk/test/Analysis/ConstantFolding/rint.ll =================================================================== --- llvm/trunk/test/Analysis/ConstantFolding/rint.ll +++ llvm/trunk/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/trunk/test/Analysis/ConstantFolding/round.ll =================================================================== --- llvm/trunk/test/Analysis/ConstantFolding/round.ll +++ llvm/trunk/test/Analysis/ConstantFolding/round.ll @@ -0,0 +1,92 @@ +; 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 @roundf(float 1.25) #0 + ret float %x +} + +; CHECK-LABEL: @constant_fold_round_f32_02 +; CHECK-NEXT: ret float -1.000000e+00 +define float @constant_fold_round_f32_02() #0 { + %x = call float @llvm.round.f32(float -1.25) #0 + ret float %x +} + +; 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 @roundf(float 1.5) #0 + ret float %x +} + +; CHECK-LABEL: @constant_fold_round_f32_04 +; CHECK-NEXT: ret float -2.000000e+00 +define float @constant_fold_round_f32_04() #0 { + %x = call float @llvm.round.f32(float -1.5) #0 + ret float %x +} + +; 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 @roundf(float 2.75) #0 + ret float %x +} + +; CHECK-LABEL: @constant_fold_round_f32_06 +; CHECK-NEXT: ret float -3.000000e+00 +define float @constant_fold_round_f32_06() #0 { + %x = call float @llvm.round.f32(float -2.75) #0 + ret float %x +} + +; 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 @round(double 1.3) #0 + ret double %x +} + +; CHECK-LABEL: @constant_fold_round_f64_02 +; CHECK-NEXT: ret double -1.000000e+00 +define double @constant_fold_round_f64_02() #0 { + %x = call double @llvm.round.f64(double -1.3) #0 + ret double %x +} + +; 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 @round(double 1.5) #0 + ret double %x +} + +; CHECK-LABEL: @constant_fold_round_f64_04 +; CHECK-NEXT: ret double -2.000000e+00 +define double @constant_fold_round_f64_04() #0 { + %x = call double @llvm.round.f64(double -1.5) #0 + ret double %x +} + +; 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 @round(double 2.7) #0 + ret double %x +} + +; CHECK-LABEL: @constant_fold_round_f64_06 +; CHECK-NEXT: ret double -3.000000e+00 +define double @constant_fold_round_f64_06() #0 { + %x = call double @llvm.round.f64(double -2.7) #0 + ret double %x +} + +attributes #0 = { nounwind readnone } Index: llvm/trunk/test/Analysis/ConstantFolding/trunc.ll =================================================================== --- llvm/trunk/test/Analysis/ConstantFolding/trunc.ll +++ llvm/trunk/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 } Index: llvm/trunk/test/Transforms/InstCombine/round.ll =================================================================== --- llvm/trunk/test/Transforms/InstCombine/round.ll +++ llvm/trunk/test/Transforms/InstCombine/round.ll @@ -1,90 +0,0 @@ -; RUN: opt -S -instcombine < %s | FileCheck %s - -declare float @llvm.round.f32(float) #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 - ret float %x -} - -; CHECK-LABEL: @constant_fold_round_f32_02 -; CHECK-NEXT: ret float -1.000000e+00 -define float @constant_fold_round_f32_02() #0 { - %x = call float @llvm.round.f32(float -1.25) #0 - ret float %x -} - -; 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 - ret float %x -} - -; CHECK-LABEL: @constant_fold_round_f32_04 -; CHECK-NEXT: ret float -2.000000e+00 -define float @constant_fold_round_f32_04() #0 { - %x = call float @llvm.round.f32(float -1.5) #0 - ret float %x -} - -; 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 - ret float %x -} - -; CHECK-LABEL: @constant_fold_round_f32_06 -; CHECK-NEXT: ret float -3.000000e+00 -define float @constant_fold_round_f32_06() #0 { - %x = call float @llvm.round.f32(float -2.75) #0 - ret float %x -} - -; 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 - ret double %x -} - -; CHECK-LABEL: @constant_fold_round_f64_02 -; CHECK-NEXT: ret double -1.000000e+00 -define double @constant_fold_round_f64_02() #0 { - %x = call double @llvm.round.f64(double -1.3) #0 - ret double %x -} - -; 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 - ret double %x -} - -; CHECK-LABEL: @constant_fold_round_f64_04 -; CHECK-NEXT: ret double -2.000000e+00 -define double @constant_fold_round_f64_04() #0 { - %x = call double @llvm.round.f64(double -1.5) #0 - ret double %x -} - -; 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 - ret double %x -} - -; CHECK-LABEL: @constant_fold_round_f64_06 -; CHECK-NEXT: ret double -3.000000e+00 -define double @constant_fold_round_f64_06() #0 { - %x = call double @llvm.round.f64(double -2.7) #0 - ret double %x -} - -attributes #0 = { nounwind readnone }