[ConstantFolding] Don't bail on folding if ConstantFoldConstantExpression fails

When folding an expression, we run ConstantFoldConstantExpression on
each operand of that expression.
However, ConstantFoldConstantExpression can fail and retur nullptr.

Previously, we would bail on further refining the expression.
Instead, use the original operand and see if we can refine a later
operand.

llvm-svn: 276959
This commit is contained in:
David Majnemer 2016-07-28 06:39:48 +00:00
parent 33e9521399
commit 19d024b2fd
2 changed files with 24 additions and 21 deletions

View File

@ -776,7 +776,9 @@ Constant *SymbolicallyEvaluateGEP(const GEPOperator *GEP,
Res = ConstantExpr::getSub(Res, CE->getOperand(1));
Res = ConstantExpr::getIntToPtr(Res, ResTy);
if (auto *ResCE = dyn_cast<ConstantExpr>(Res))
Res = ConstantFoldConstantExpression(ResCE, DL, TLI);
if (auto *FoldedRes =
ConstantFoldConstantExpression(ResCE, DL, TLI))
Res = FoldedRes;
return Res;
}
}
@ -985,7 +987,8 @@ Constant *llvm::ConstantFoldInstruction(Instruction *I, const DataLayout &DL,
return nullptr;
// Fold the PHI's operands.
if (auto *NewC = dyn_cast<ConstantExpr>(C))
C = ConstantFoldConstantExpression(NewC, DL, TLI);
if (auto *FoldedC = ConstantFoldConstantExpression(NewC, DL, TLI))
C = FoldedC;
// If the incoming value is a different constant to
// the one we saw previously, then give up.
if (CommonValue && C != CommonValue)
@ -1007,12 +1010,9 @@ Constant *llvm::ConstantFoldInstruction(Instruction *I, const DataLayout &DL,
for (const Use &OpU : I->operands()) {
auto *Op = cast<Constant>(&OpU);
// Fold the Instruction's operands.
if (auto *NewCE = dyn_cast<ConstantExpr>(Op)) {
auto *FoldedOp = ConstantFoldConstantExpression(NewCE, DL, TLI);
if (!FoldedOp)
return nullptr;
Op = FoldedOp;
}
if (auto *NewCE = dyn_cast<ConstantExpr>(Op))
if (auto *FoldedOp = ConstantFoldConstantExpression(NewCE, DL, TLI))
Op = FoldedOp;
Ops.push_back(Op);
}
@ -1042,22 +1042,26 @@ Constant *llvm::ConstantFoldInstruction(Instruction *I, const DataLayout &DL,
namespace {
Constant *
ConstantFoldConstantExpressionImpl(const ConstantExpr *CE, const DataLayout &DL,
const TargetLibraryInfo *TLI,
SmallPtrSetImpl<ConstantExpr *> &FoldedOps) {
Constant *ConstantFoldConstantExpressionImpl(
const ConstantExpr *CE, const DataLayout &DL, const TargetLibraryInfo *TLI,
SmallDenseMap<ConstantExpr *, Constant *> &FoldedOps) {
SmallVector<Constant *, 8> Ops;
for (const Use &NewU : CE->operands()) {
auto *NewC = cast<Constant>(&NewU);
// Recursively fold the ConstantExpr's operands. If we have already folded
// a ConstantExpr, we don't have to process it again.
if (auto *NewCE = dyn_cast<ConstantExpr>(NewC)) {
if (FoldedOps.insert(NewCE).second){
auto *FoldedC =
ConstantFoldConstantExpressionImpl(NewCE, DL, TLI, FoldedOps);
if (!FoldedC)
return nullptr;
NewC = FoldedC;
auto It = FoldedOps.find(NewCE);
if (It == FoldedOps.end()) {
if (auto *FoldedC =
ConstantFoldConstantExpressionImpl(NewCE, DL, TLI, FoldedOps)) {
NewC = FoldedC;
FoldedOps.insert({NewCE, FoldedC});
} else {
FoldedOps.insert({NewCE, NewCE});
}
} else {
NewC = It->second;
}
}
Ops.push_back(NewC);
@ -1076,7 +1080,7 @@ ConstantFoldConstantExpressionImpl(const ConstantExpr *CE, const DataLayout &DL,
Constant *llvm::ConstantFoldConstantExpression(const ConstantExpr *CE,
const DataLayout &DL,
const TargetLibraryInfo *TLI) {
SmallPtrSet<ConstantExpr *, 4> FoldedOps;
SmallDenseMap<ConstantExpr *, Constant *> FoldedOps;
return ConstantFoldConstantExpressionImpl(CE, DL, TLI, FoldedOps);
}

View File

@ -10,5 +10,4 @@ entry:
}
; CHECK-LABEL: @test1(
; CHECK: %[[ie:.*]] = insertelement <2 x i16> <i16 undef, i16 0>, i16 extractvalue (%S select (i1 icmp eq (i16 extractelement (<2 x i16> bitcast (<1 x i32> <i32 1> to <2 x i16>), i32 0), i16 0), %S zeroinitializer, %S { i16 0, i32 1 }), 0), i32 0
; CHECK: ret <2 x i16> %[[ie]]
; CHECK: ret <2 x i16> <i16 extractvalue (%S select (i1 icmp eq (i16 extractelement (<2 x i16> bitcast (<1 x i32> <i32 1> to <2 x i16>), i32 0), i16 0), %S zeroinitializer, %S { i16 0, i32 1 }), 0), i16 0>