diff --git a/lib/Transforms/Scalar/Reassociate.cpp b/lib/Transforms/Scalar/Reassociate.cpp index 0d5ad7311fb..02cf708311b 100644 --- a/lib/Transforms/Scalar/Reassociate.cpp +++ b/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(V) && - cast(V)->getOpcode() == Opcode) + cast(V)->getOpcode() == Opcode && + (!isa(V) || + cast(V)->hasUnsafeAlgebra())) return cast(V); return nullptr; } @@ -246,7 +248,9 @@ static BinaryOperator *isReassociableOp(Value *V, unsigned Opcode1, unsigned Opcode2) { if (V->hasOneUse() && isa(V) && (cast(V)->getOpcode() == Opcode1 || - cast(V)->getOpcode() == Opcode2)) + cast(V)->getOpcode() == Opcode2) && + (!isa(V) || + cast(V)->hasUnsafeAlgebra())) return cast(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(Op) || - cast(Op)->getOpcode() != Opcode) && + cast(Op)->getOpcode() != Opcode + || (isa(Op) && + !cast(Op)->hasUnsafeAlgebra())) && "Should have been handled above!"); assert(Op->hasOneUse() && "Has uses outside the expression tree!"); diff --git a/test/Transforms/Reassociate/mixed-fast-nonfast-fp.ll b/test/Transforms/Reassociate/mixed-fast-nonfast-fp.ll new file mode 100644 index 00000000000..f51c0c17fe7 --- /dev/null +++ b/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 +}