diff options
| author | Chad Rosier <mcrosier@codeaurora.org> | 2014-11-06 16:46:37 +0000 |
|---|---|---|
| committer | Chad Rosier <mcrosier@codeaurora.org> | 2014-11-06 16:46:37 +0000 |
| commit | ac6a2f532ca67d0fc9be24f46683b108234cae57 (patch) | |
| tree | 2fd088f56f4e8d227306e678f083e178a7820c52 | |
| parent | b70e27ca7b016109a9ce3dfef1f0924db8e00212 (diff) | |
| download | bcm5719-llvm-ac6a2f532ca67d0fc9be24f46683b108234cae57.tar.gz bcm5719-llvm-ac6a2f532ca67d0fc9be24f46683b108234cae57.zip | |
[Reassociate] Don't reassociate when mixing regular and fast-math FP
instructions. Inlining might cause such cases and it's not valid to
reassociate floating-point instructions without the unsafe algebra flag.
Patch by Mehdi Amini <mehdi_amini@apple.com>!
llvm-svn: 221462
| -rw-r--r-- | llvm/lib/Transforms/Scalar/Reassociate.cpp | 12 | ||||
| -rw-r--r-- | llvm/test/Transforms/Reassociate/mixed-fast-nonfast-fp.ll | 18 |
2 files changed, 27 insertions, 3 deletions
diff --git a/llvm/lib/Transforms/Scalar/Reassociate.cpp b/llvm/lib/Transforms/Scalar/Reassociate.cpp index 0d5ad7311fb..02cf708311b 100644 --- a/llvm/lib/Transforms/Scalar/Reassociate.cpp +++ b/llvm/lib/Transforms/Scalar/Reassociate.cpp @@ -237,7 +237,9 @@ FunctionPass *llvm::createReassociatePass() { return new Reassociate(); } /// opcode and if it only has one use. static BinaryOperator *isReassociableOp(Value *V, unsigned Opcode) { if (V->hasOneUse() && isa<Instruction>(V) && - cast<Instruction>(V)->getOpcode() == Opcode) + cast<Instruction>(V)->getOpcode() == Opcode && + (!isa<FPMathOperator>(V) || + cast<Instruction>(V)->hasUnsafeAlgebra())) return cast<BinaryOperator>(V); return nullptr; } @@ -246,7 +248,9 @@ static BinaryOperator *isReassociableOp(Value *V, unsigned Opcode1, unsigned Opcode2) { if (V->hasOneUse() && isa<Instruction>(V) && (cast<Instruction>(V)->getOpcode() == Opcode1 || - cast<Instruction>(V)->getOpcode() == Opcode2)) + cast<Instruction>(V)->getOpcode() == Opcode2) && + (!isa<FPMathOperator>(V) || + cast<Instruction>(V)->hasUnsafeAlgebra())) return cast<BinaryOperator>(V); return nullptr; } @@ -662,7 +666,9 @@ static bool LinearizeExprTree(BinaryOperator *I, // expression. This means that it can safely be modified. See if we // can usefully morph it into an expression of the right kind. assert((!isa<Instruction>(Op) || - cast<Instruction>(Op)->getOpcode() != Opcode) && + cast<Instruction>(Op)->getOpcode() != Opcode + || (isa<FPMathOperator>(Op) && + !cast<Instruction>(Op)->hasUnsafeAlgebra())) && "Should have been handled above!"); assert(Op->hasOneUse() && "Has uses outside the expression tree!"); diff --git a/llvm/test/Transforms/Reassociate/mixed-fast-nonfast-fp.ll b/llvm/test/Transforms/Reassociate/mixed-fast-nonfast-fp.ll new file mode 100644 index 00000000000..f51c0c17fe7 --- /dev/null +++ b/llvm/test/Transforms/Reassociate/mixed-fast-nonfast-fp.ll @@ -0,0 +1,18 @@ +; RUN: opt -reassociate %s -S | FileCheck %s + +define float @foo(float %a,float %b, float %c) { +; CHECK: %mul3 = fmul float %a, %b +; CHECK-NEXT: fmul fast float %c, 2.000000e+00 +; CHECK-NEXT: fadd fast float %factor, %b +; CHECK-NEXT: fmul fast float %tmp1, %a +; CHECK-NEXT: fadd fast float %tmp2, %mul3 +; CHECK-NEXT: ret float + %mul1 = fmul fast float %a, %c + %mul2 = fmul fast float %a, %b + %mul3 = fmul float %a, %b + %mul4 = fmul fast float %a, %c + %add1 = fadd fast float %mul1, %mul3 + %add2 = fadd fast float %mul4, %mul2 + %add3 = fadd fast float %add1, %add2 + ret float %add3 +} |

