diff options
author | Matt Arsenault <Matthew.Arsenault@amd.com> | 2014-03-05 00:02:00 +0000 |
---|---|---|
committer | Matt Arsenault <Matthew.Arsenault@amd.com> | 2014-03-05 00:02:00 +0000 |
commit | 8377858c553bd208eb8f505c010d65e698cc9452 (patch) | |
tree | 3e5557e442e451632319ab8c792cf3ba07d07722 | |
parent | f8ecf9b44755edbd923b0445fa8950aa0c7a500d (diff) | |
download | bcm5719-llvm-8377858c553bd208eb8f505c010d65e698cc9452.tar.gz bcm5719-llvm-8377858c553bd208eb8f505c010d65e698cc9452.zip |
Allow constant folding of fma and fmuladd
llvm-svn: 202914
-rw-r--r-- | llvm/lib/Analysis/ConstantFolding.cpp | 27 | ||||
-rw-r--r-- | llvm/test/Transforms/InstCombine/constant-fold-math.ll | 39 |
2 files changed, 66 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp index 10f8e4ed684..254f2d9f50b 100644 --- a/llvm/lib/Analysis/ConstantFolding.cpp +++ b/llvm/lib/Analysis/ConstantFolding.cpp @@ -1193,6 +1193,8 @@ bool llvm::canConstantFoldCallTo(const Function *F) { case Intrinsic::ctpop: case Intrinsic::ctlz: case Intrinsic::cttz: + case Intrinsic::fma: + case Intrinsic::fmuladd: case Intrinsic::sadd_with_overflow: case Intrinsic::uadd_with_overflow: case Intrinsic::ssub_with_overflow: @@ -1615,5 +1617,30 @@ llvm::ConstantFoldCall(Function *F, ArrayRef<Constant *> Operands, } return 0; } + + if (Operands.size() != 3) + return 0; + + if (const ConstantFP *Op1 = dyn_cast<ConstantFP>(Operands[0])) { + if (const ConstantFP *Op2 = dyn_cast<ConstantFP>(Operands[1])) { + if (const ConstantFP *Op3 = dyn_cast<ConstantFP>(Operands[2])) { + switch (F->getIntrinsicID()) { + default: break; + case Intrinsic::fma: + case Intrinsic::fmuladd: { + APFloat V = Op1->getValueAPF(); + APFloat::opStatus s = V.fusedMultiplyAdd(Op2->getValueAPF(), + Op3->getValueAPF(), + APFloat::rmNearestTiesToEven); + if (s != APFloat::opInvalidOp) + return ConstantFP::get(Ty->getContext(), V); + + return 0; + } + } + } + } + } + return 0; } diff --git a/llvm/test/Transforms/InstCombine/constant-fold-math.ll b/llvm/test/Transforms/InstCombine/constant-fold-math.ll new file mode 100644 index 00000000000..00fceb19151 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/constant-fold-math.ll @@ -0,0 +1,39 @@ +; RUN: opt -S -instcombine < %s | FileCheck %s + +declare float @llvm.fma.f32(float, float, float) #0 +declare float @llvm.fmuladd.f32(float, float, float) #0 + +declare double @llvm.fma.f64(double, double, double) #0 +declare double @llvm.fmuladd.f64(double, double, double) #0 + + + +; CHECK-LABEL: @constant_fold_fma_f32 +; CHECK-NEXT: ret float 6.000000e+00 +define float @constant_fold_fma_f32() #0 { + %x = call float @llvm.fma.f32(float 1.0, float 2.0, float 4.0) #0 + ret float %x +} + +; CHECK-LABEL: @constant_fold_fmuladd_f32 +; CHECK-NEXT: ret float 6.000000e+00 +define float @constant_fold_fmuladd_f32() #0 { + %x = call float @llvm.fmuladd.f32(float 1.0, float 2.0, float 4.0) #0 + ret float %x +} + +; CHECK-LABEL: @constant_fold_fma_f64 +; CHECK-NEXT: ret double 6.000000e+00 +define double @constant_fold_fma_f64() #0 { + %x = call double @llvm.fma.f64(double 1.0, double 2.0, double 4.0) #0 + ret double %x +} + +; CHECK-LABEL: @constant_fold_fmuladd_f64 +; CHECK-NEXT: ret double 6.000000e+00 +define double @constant_fold_fmuladd_f64() #0 { + %x = call double @llvm.fmuladd.f64(double 1.0, double 2.0, double 4.0) #0 + ret double %x +} + +attributes #0 = { nounwind readnone } |