Skip to content

Commit

Permalink
Fix all the remaining lost-fast-math-flags bugs I've been able to fin…
Browse files Browse the repository at this point in the history
…d. 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.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@199629 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
resistor committed Jan 20, 2014
1 parent f55ec9a commit 1e1446b
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 10 deletions.
34 changes: 26 additions & 8 deletions lib/Transforms/InstCombine/InstCombineAddSub.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -483,6 +483,11 @@ Value *FAddCombine::performFactorization(Instruction *I) {
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) :
Expand All @@ -491,12 +496,20 @@ Value *FAddCombine::performFactorization(Instruction *I) {
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) {
Expand Down Expand Up @@ -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
Expand All @@ -771,11 +787,13 @@ Value *FAddCombine::createFDiv(Value *Opnd0, Value *Opnd1) {
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());
Expand Down
10 changes: 10 additions & 0 deletions lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1111,13 +1111,23 @@ Instruction *InstCombiner::visitFDiv(BinaryOperator &I) {
//
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)))) {
// Z / (X/Y) => Z*Y / X
//
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);
}
}
Expand Down
15 changes: 13 additions & 2 deletions lib/Transforms/InstCombine/InstructionCombining.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,12 @@ bool InstCombiner::SimplifyAssociativeOrCommutative(BinaryOperator &I) {

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);
Expand Down Expand Up @@ -566,9 +572,14 @@ static Value *FoldOperationIntoSelectOperand(Instruction &I, Value *SO,
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");
Expand Down
18 changes: 18 additions & 0 deletions test/Transforms/InstCombine/fdiv.ll
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,21 @@ define float @test4(float %x) nounwind readnone ssp {
; 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
}
10 changes: 10 additions & 0 deletions test/Transforms/InstCombine/fmul.ll
Original file line number Diff line number Diff line change
Expand Up @@ -113,3 +113,13 @@ define <4 x float> @test10(<4 x float> %x) {
; 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
}
10 changes: 10 additions & 0 deletions test/Transforms/InstCombine/select-2.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

0 comments on commit 1e1446b

Please sign in to comment.