From 19d024b2fd930acad84fe6c33c2af93725408875 Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Thu, 28 Jul 2016 06:39:48 +0000 Subject: [PATCH] [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 --- llvm/lib/Analysis/ConstantFolding.cpp | 42 +++++++++++--------- llvm/test/Transforms/InstSimplify/pr28725.ll | 3 +- 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp index 8f67492971d2..1a6a54b9a763 100644 --- a/llvm/lib/Analysis/ConstantFolding.cpp +++ b/llvm/lib/Analysis/ConstantFolding.cpp @@ -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(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(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(&OpU); // Fold the Instruction's operands. - if (auto *NewCE = dyn_cast(Op)) { - auto *FoldedOp = ConstantFoldConstantExpression(NewCE, DL, TLI); - if (!FoldedOp) - return nullptr; - Op = FoldedOp; - } + if (auto *NewCE = dyn_cast(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 &FoldedOps) { +Constant *ConstantFoldConstantExpressionImpl( + const ConstantExpr *CE, const DataLayout &DL, const TargetLibraryInfo *TLI, + SmallDenseMap &FoldedOps) { SmallVector Ops; for (const Use &NewU : CE->operands()) { auto *NewC = cast(&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(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 FoldedOps; + SmallDenseMap FoldedOps; return ConstantFoldConstantExpressionImpl(CE, DL, TLI, FoldedOps); } diff --git a/llvm/test/Transforms/InstSimplify/pr28725.ll b/llvm/test/Transforms/InstSimplify/pr28725.ll index bc6b30a5885a..420bf4d0e54c 100644 --- a/llvm/test/Transforms/InstSimplify/pr28725.ll +++ b/llvm/test/Transforms/InstSimplify/pr28725.ll @@ -10,5 +10,4 @@ entry: } ; CHECK-LABEL: @test1( -; CHECK: %[[ie:.*]] = insertelement <2 x i16> , i16 extractvalue (%S select (i1 icmp eq (i16 extractelement (<2 x i16> bitcast (<1 x i32> 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> bitcast (<1 x i32> to <2 x i16>), i32 0), i16 0), %S zeroinitializer, %S { i16 0, i32 1 }), 0), i16 0>