[llvm] r199629 - Fix all the remaining lost-fast-math-flags bugs I've been able to find. The most important of these are cases in the generic logic for combining BinaryOperators.

Owen Anderson resistor at mac.com
Sun Jan 19 23:44:54 PST 2014


Author: resistor
Date: Mon Jan 20 01:44:53 2014
New Revision: 199629

URL: http://llvm.org/viewvc/llvm-project?rev=199629&view=rev
Log:
Fix all the remaining lost-fast-math-flags bugs I've been able to find.  The most important of these are cases in the generic logic for combining BinaryOperators.
This logic hadn't been updated to handle FastMathFlags, and it took me a while to detect it because it doesn't show up in a simple search for CreateFAdd.

Modified:
    llvm/trunk/lib/Transforms/InstCombine/InstCombineAddSub.cpp
    llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
    llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp
    llvm/trunk/test/Transforms/InstCombine/fdiv.ll
    llvm/trunk/test/Transforms/InstCombine/fmul.ll
    llvm/trunk/test/Transforms/InstCombine/select-2.ll

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineAddSub.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineAddSub.cpp?rev=199629&r1=199628&r2=199629&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineAddSub.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineAddSub.cpp Mon Jan 20 01:44:53 2014
@@ -175,7 +175,7 @@ namespace {
     Value *createFDiv(Value *Opnd0, Value *Opnd1);
     Value *createFNeg(Value *V);
     Value *createNaryFAdd(const AddendVect& Opnds, unsigned InstrQuota);
-    void createInstPostProc(Instruction *NewInst);
+    void createInstPostProc(Instruction *NewInst, bool NoNumber = false);
 
     InstCombiner::BuilderTy *Builder;
     Instruction *Instr;
@@ -483,6 +483,11 @@ Value *FAddCombine::performFactorization
   if (!Factor)
     return 0;
 
+  FastMathFlags Flags;
+  Flags.setUnsafeAlgebra();
+  if (I0) Flags &= I->getFastMathFlags();
+  if (I1) Flags &= I->getFastMathFlags();
+
   // Create expression "NewAddSub = AddSub0 +/- AddsSub1"
   Value *NewAddSub = (I->getOpcode() == Instruction::FAdd) ?
                       createFAdd(AddSub0, AddSub1) :
@@ -491,12 +496,20 @@ Value *FAddCombine::performFactorization
     const APFloat &F = CFP->getValueAPF();
     if (!F.isNormal())
       return 0;
-  }
+  } else if (Instruction *II = dyn_cast<Instruction>(NewAddSub))
+    II->setFastMathFlags(Flags);
 
-  if (isMpy)
-    return createFMul(Factor, NewAddSub);
+  if (isMpy) {
+    Value *RI = createFMul(Factor, NewAddSub);
+    if (Instruction *II = dyn_cast<Instruction>(RI))
+      II->setFastMathFlags(Flags);
+    return RI;
+  }
 
-  return createFDiv(NewAddSub, Factor);
+  Value *RI = createFDiv(NewAddSub, Factor);
+  if (Instruction *II = dyn_cast<Instruction>(RI))
+    II->setFastMathFlags(Flags);
+  return RI;
 }
 
 Value *FAddCombine::simplify(Instruction *I) {
@@ -746,7 +759,10 @@ Value *FAddCombine::createFSub
 
 Value *FAddCombine::createFNeg(Value *V) {
   Value *Zero = cast<Value>(ConstantFP::get(V->getType(), 0.0));
-  return createFSub(Zero, V);
+  Value *NewV = createFSub(Zero, V);
+  if (Instruction *I = dyn_cast<Instruction>(NewV))
+    createInstPostProc(I, true); // fneg's don't receive instruction numbers.
+  return NewV;
 }
 
 Value *FAddCombine::createFAdd
@@ -771,11 +787,13 @@ Value *FAddCombine::createFDiv(Value *Op
   return V;
 }
 
-void FAddCombine::createInstPostProc(Instruction *NewInstr) {
+void FAddCombine::createInstPostProc(Instruction *NewInstr,
+                                     bool NoNumber) {
   NewInstr->setDebugLoc(Instr->getDebugLoc());
 
   // Keep track of the number of instruction created.
-  incCreateInstNum();
+  if (!NoNumber)
+    incCreateInstNum();
 
   // Propagate fast-math flags
   NewInstr->setFastMathFlags(Instr->getFastMathFlags());

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp?rev=199629&r1=199628&r2=199629&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp Mon Jan 20 01:44:53 2014
@@ -1111,6 +1111,11 @@ Instruction *InstCombiner::visitFDiv(Bin
       //
       if (!isa<Constant>(Y) || !isa<Constant>(Op1)) {
         NewInst = Builder->CreateFMul(Y, Op1);
+        if (Instruction *RI = dyn_cast<Instruction>(NewInst)) {
+          FastMathFlags Flags = I.getFastMathFlags();
+          Flags &= cast<Instruction>(Op0)->getFastMathFlags();
+          RI->setFastMathFlags(Flags);
+        }
         SimpR = BinaryOperator::CreateFDiv(X, NewInst);
       }
     } else if (Op1->hasOneUse() && match(Op1, m_FDiv(m_Value(X), m_Value(Y)))) {
@@ -1118,6 +1123,11 @@ Instruction *InstCombiner::visitFDiv(Bin
       //
       if (!isa<Constant>(Y) || !isa<Constant>(Op0)) {
         NewInst = Builder->CreateFMul(Op0, Y);
+        if (Instruction *RI = dyn_cast<Instruction>(NewInst)) {
+          FastMathFlags Flags = I.getFastMathFlags();
+          Flags &= cast<Instruction>(Op1)->getFastMathFlags();
+          RI->setFastMathFlags(Flags);
+        }
         SimpR = BinaryOperator::CreateFDiv(NewInst, X);
       }
     }

Modified: llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp?rev=199629&r1=199628&r2=199629&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp Mon Jan 20 01:44:53 2014
@@ -319,6 +319,12 @@ bool InstCombiner::SimplifyAssociativeOr
 
         Constant *Folded = ConstantExpr::get(Opcode, C1, C2);
         BinaryOperator *New = BinaryOperator::Create(Opcode, A, B);
+        if (isa<FPMathOperator>(New)) {
+          FastMathFlags Flags = I.getFastMathFlags();
+          Flags &= Op0->getFastMathFlags();
+          Flags &= Op1->getFastMathFlags();
+          New->setFastMathFlags(Flags);
+        }
         InsertNewInstWith(New, I);
         New->takeName(Op1);
         I.setOperand(0, New);
@@ -566,9 +572,14 @@ static Value *FoldOperationIntoSelectOpe
   if (!ConstIsRHS)
     std::swap(Op0, Op1);
 
-  if (BinaryOperator *BO = dyn_cast<BinaryOperator>(&I))
-    return IC->Builder->CreateBinOp(BO->getOpcode(), Op0, Op1,
+  if (BinaryOperator *BO = dyn_cast<BinaryOperator>(&I)) {
+    Value *RI = IC->Builder->CreateBinOp(BO->getOpcode(), Op0, Op1,
                                     SO->getName()+".op");
+    Instruction *FPInst = dyn_cast<Instruction>(RI);
+    if (FPInst && isa<FPMathOperator>(FPInst))
+      FPInst->copyFastMathFlags(BO);
+    return RI;
+  }
   if (ICmpInst *CI = dyn_cast<ICmpInst>(&I))
     return IC->Builder->CreateICmp(CI->getPredicate(), Op0, Op1,
                                    SO->getName()+".cmp");

Modified: llvm/trunk/test/Transforms/InstCombine/fdiv.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/fdiv.ll?rev=199629&r1=199628&r2=199629&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/fdiv.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/fdiv.ll Mon Jan 20 01:44:53 2014
@@ -31,3 +31,21 @@ define float @test4(float %x) nounwind r
 ; CHECK-LABEL: @test4(
 ; CHECK-NEXT: fmul fast float %x, 1.250000e-01
 }
+
+define float @test5(float %x, float %y, float %z) nounwind readnone ssp {
+  %div1 = fdiv fast float %x, %y
+  %div2 = fdiv fast float %div1, %z
+  ret float %div2
+; CHECK-LABEL: @test5(
+; CHECK-NEXT: fmul fast
+; CHECK-NEXT: fdiv fast
+}
+
+define float @test6(float %x, float %y, float %z) nounwind readnone ssp {
+  %div1 = fdiv fast float %x, %y
+  %div2 = fdiv fast float %z, %div1
+  ret float %div2
+; CHECK-LABEL: @test6(
+; CHECK-NEXT: fmul fast
+; CHECK-NEXT: fdiv fast
+}

Modified: llvm/trunk/test/Transforms/InstCombine/fmul.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/fmul.ll?rev=199629&r1=199628&r2=199629&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/fmul.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/fmul.ll Mon Jan 20 01:44:53 2014
@@ -113,3 +113,13 @@ define <4 x float> @test10(<4 x float> %
 ; CHECK-NOT: fmul
 ; CHECK: fsub
 }
+
+define float @test11(float %x, float %y) {
+  %a = fadd fast float %x, 1.0
+  %b = fadd fast float %y, 2.0
+  %c = fadd fast float %a, %b
+  ret float %c
+; CHECK-LABEL: @test11(
+; CHECK-NOT: fadd float
+; CHECK: fadd fast float
+}

Modified: llvm/trunk/test/Transforms/InstCombine/select-2.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/select-2.ll?rev=199629&r1=199628&r2=199629&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/select-2.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/select-2.ll Mon Jan 20 01:44:53 2014
@@ -19,3 +19,13 @@ define i32 @t2(i32 %c, i32 %x) nounwind
        %t3 = select i1 %t1, i32 %t2, i32 %x
        ret i32 %t3
 }
+
+define float @t3(float %x, float %y) nounwind {
+  %t1 = fcmp ogt float %x, %y
+  %t2 = select i1 %t1, float %x, float 1.0
+  %t3 = fadd fast float %t2, 1.0
+  ret float %t3
+; CHECK-LABEL: @t3(
+; CHECK: fadd fast
+; CHECK: select
+}





More information about the llvm-commits mailing list