[llvm] r267139 - [InstCombine] Preserve fast math flags when combining PHIs
Silviu Baranga via llvm-commits
llvm-commits at lists.llvm.org
Fri Apr 22 04:21:36 PDT 2016
Author: sbaranga
Date: Fri Apr 22 06:21:36 2016
New Revision: 267139
URL: http://llvm.org/viewvc/llvm-project?rev=267139&view=rev
Log:
[InstCombine] Preserve fast math flags when combining PHIs
Summary:
When optimizing PHIs which have inputs floating point binary
operators, we preserve all IR flags except the fast math
flags.
This change removes the logic which tracked some of the IR flags
(no wrap, exact) and replaces it by doing an and on the IR flags of
all inputs to the PHI - which will also handle the fast math
flags.
Reviewers: majnemer
Subscribers: llvm-commits
Differential Revision: http://reviews.llvm.org/D19370
Added:
llvm/trunk/test/Transforms/InstCombine/phi-preserve-ir-flags.ll
Modified:
llvm/trunk/lib/Transforms/InstCombine/InstCombinePHI.cpp
Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombinePHI.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombinePHI.cpp?rev=267139&r1=267138&r2=267139&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombinePHI.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombinePHI.cpp Fri Apr 22 06:21:36 2016
@@ -35,15 +35,6 @@ Instruction *InstCombiner::FoldPHIArgBin
Type *LHSType = LHSVal->getType();
Type *RHSType = RHSVal->getType();
- bool isNUW = false, isNSW = false, isExact = false;
- if (OverflowingBinaryOperator *BO =
- dyn_cast<OverflowingBinaryOperator>(FirstInst)) {
- isNUW = BO->hasNoUnsignedWrap();
- isNSW = BO->hasNoSignedWrap();
- } else if (PossiblyExactOperator *PEO =
- dyn_cast<PossiblyExactOperator>(FirstInst))
- isExact = PEO->isExact();
-
// Scan to see if all operands are the same opcode, and all have one use.
for (unsigned i = 1; i != PN.getNumIncomingValues(); ++i) {
Instruction *I = dyn_cast<Instruction>(PN.getIncomingValue(i));
@@ -59,13 +50,6 @@ Instruction *InstCombiner::FoldPHIArgBin
if (CI->getPredicate() != cast<CmpInst>(FirstInst)->getPredicate())
return nullptr;
- if (isNUW)
- isNUW = cast<OverflowingBinaryOperator>(I)->hasNoUnsignedWrap();
- if (isNSW)
- isNSW = cast<OverflowingBinaryOperator>(I)->hasNoSignedWrap();
- if (isExact)
- isExact = cast<PossiblyExactOperator>(I)->isExact();
-
// Keep track of which operand needs a phi node.
if (I->getOperand(0) != LHSVal) LHSVal = nullptr;
if (I->getOperand(1) != RHSVal) RHSVal = nullptr;
@@ -124,9 +108,12 @@ Instruction *InstCombiner::FoldPHIArgBin
BinaryOperator *BinOp = cast<BinaryOperator>(FirstInst);
BinaryOperator *NewBinOp =
BinaryOperator::Create(BinOp->getOpcode(), LHSVal, RHSVal);
- if (isNUW) NewBinOp->setHasNoUnsignedWrap();
- if (isNSW) NewBinOp->setHasNoSignedWrap();
- if (isExact) NewBinOp->setIsExact();
+
+ NewBinOp->copyIRFlags(PN.getIncomingValue(0));
+
+ for (unsigned i = 1, e = PN.getNumIncomingValues(); i != e; ++i)
+ NewBinOp->andIRFlags(PN.getIncomingValue(i));
+
NewBinOp->setDebugLoc(FirstInst->getDebugLoc());
return NewBinOp;
}
@@ -497,7 +484,6 @@ Instruction *InstCombiner::FoldPHIArgOpI
// code size and simplifying code.
Constant *ConstantOp = nullptr;
Type *CastSrcTy = nullptr;
- bool isNUW = false, isNSW = false, isExact = false;
if (isa<CastInst>(FirstInst)) {
CastSrcTy = FirstInst->getOperand(0)->getType();
@@ -514,14 +500,6 @@ Instruction *InstCombiner::FoldPHIArgOpI
ConstantOp = dyn_cast<Constant>(FirstInst->getOperand(1));
if (!ConstantOp)
return FoldPHIArgBinOpIntoPHI(PN);
-
- if (OverflowingBinaryOperator *BO =
- dyn_cast<OverflowingBinaryOperator>(FirstInst)) {
- isNUW = BO->hasNoUnsignedWrap();
- isNSW = BO->hasNoSignedWrap();
- } else if (PossiblyExactOperator *PEO =
- dyn_cast<PossiblyExactOperator>(FirstInst))
- isExact = PEO->isExact();
} else {
return nullptr; // Cannot fold this operation.
}
@@ -537,13 +515,6 @@ Instruction *InstCombiner::FoldPHIArgOpI
} else if (I->getOperand(1) != ConstantOp) {
return nullptr;
}
-
- if (isNUW)
- isNUW = cast<OverflowingBinaryOperator>(I)->hasNoUnsignedWrap();
- if (isNSW)
- isNSW = cast<OverflowingBinaryOperator>(I)->hasNoSignedWrap();
- if (isExact)
- isExact = cast<PossiblyExactOperator>(I)->isExact();
}
// Okay, they are all the same operation. Create a new PHI node of the
@@ -584,9 +555,11 @@ Instruction *InstCombiner::FoldPHIArgOpI
if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(FirstInst)) {
BinOp = BinaryOperator::Create(BinOp->getOpcode(), PhiVal, ConstantOp);
- if (isNUW) BinOp->setHasNoUnsignedWrap();
- if (isNSW) BinOp->setHasNoSignedWrap();
- if (isExact) BinOp->setIsExact();
+ BinOp->copyIRFlags(PN.getIncomingValue(0));
+
+ for (unsigned i = 1, e = PN.getNumIncomingValues(); i != e; ++i)
+ BinOp->andIRFlags(PN.getIncomingValue(i));
+
BinOp->setDebugLoc(FirstInst->getDebugLoc());
return BinOp;
}
Added: llvm/trunk/test/Transforms/InstCombine/phi-preserve-ir-flags.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/phi-preserve-ir-flags.ll?rev=267139&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/phi-preserve-ir-flags.ll (added)
+++ llvm/trunk/test/Transforms/InstCombine/phi-preserve-ir-flags.ll Fri Apr 22 06:21:36 2016
@@ -0,0 +1,89 @@
+; RUN: opt < %s -instcombine -S -o - | FileCheck %s
+
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
+
+; CHECK-LABEL: define float @func1(
+define float @func1(float %a, float %b, float %c, i1 %cond) {
+entry:
+ br i1 %cond, label %cond.true, label %cond.false
+
+cond.true:
+ %sub0 = fsub fast float %a, %b
+ br label %cond.end
+
+cond.false:
+ %sub1 = fsub fast float %a, %c
+ br label %cond.end
+
+; The fast-math flags should always be transfered if possible.
+; CHECK-LABEL: cond.end
+; CHECK [[PHI:%[^ ]*]] = phi float [ %b, %cond.true ], [ %c, %cond.false ]
+; CHECK fsub fast float %a, [[PHI]]
+cond.end:
+ %e = phi float [ %sub0, %cond.true ], [ %sub1, %cond.false ]
+ ret float %e
+}
+
+; CHECK-LABEL: define float @func2(
+define float @func2(float %a, float %b, float %c, i1 %cond) {
+entry:
+ br i1 %cond, label %cond.true, label %cond.false
+
+cond.true:
+ %sub0 = fsub fast float %a, %b
+ br label %cond.end
+
+cond.false:
+ %sub1 = fsub float %a, %c
+ br label %cond.end
+
+; The fast-math flags should always be transfered if possible.
+; CHECK-LABEL: cond.end
+; CHECK [[PHI:%[^ ]*]] = phi float [ %b, %cond.true ], [ %c, %cond.false ]
+; CHECK fsub float %a, [[PHI]]
+cond.end:
+ %e = phi float [ %sub0, %cond.true ], [ %sub1, %cond.false ]
+ ret float %e
+}
+
+; CHECK-LABEL: define float @func3(
+define float @func3(float %a, float %b, float %c, i1 %cond) {
+entry:
+ br i1 %cond, label %cond.true, label %cond.false
+
+cond.true:
+ %sub0 = fsub fast float %a, 2.0
+ br label %cond.end
+
+cond.false:
+ %sub1 = fsub fast float %b, 2.0
+ br label %cond.end
+
+; CHECK-LABEL: cond.end
+; CHECK [[PHI:%[^ ]*]] = phi float [ %a, %cond.true ], [ %b, %cond.false ]
+; CHECK fadd fast float %a, [[PHI]]
+cond.end:
+ %e = phi float [ %sub0, %cond.true ], [ %sub1, %cond.false ]
+ ret float %e
+}
+
+; CHECK-LABEL: define float @func4(
+define float @func4(float %a, float %b, float %c, i1 %cond) {
+entry:
+ br i1 %cond, label %cond.true, label %cond.false
+
+cond.true:
+ %sub0 = fsub fast float %a, 2.0
+ br label %cond.end
+
+cond.false:
+ %sub1 = fsub float %b, 2.0
+ br label %cond.end
+
+; CHECK-LABEL: cond.end
+; CHECK [[PHI:%[^ ]*]] = phi float [ %a, %cond.true ], [ %b, %cond.false ]
+; CHECK fadd float %a, [[PHI]]
+cond.end:
+ %e = phi float [ %sub0, %cond.true ], [ %sub1, %cond.false ]
+ ret float %e
+}
More information about the llvm-commits
mailing list