Reapply r155682, making constant folding more consistent, with a fix to work

properly with how the code handles all-undef PHI nodes.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155721 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Dan Gohman 2012-04-27 17:50:22 +00:00
parent 04a09a461b
commit 03e091f0b5
5 changed files with 90 additions and 38 deletions

View File

@ -780,14 +780,21 @@ Constant *llvm::ConstantFoldInstruction(Instruction *I,
// all operands are constants.
if (isa<UndefValue>(Incoming))
continue;
// If the incoming value is not a constant, or is a different constant to
// the one we saw previously, then give up.
// If the incoming value is not a constant, then give up.
Constant *C = dyn_cast<Constant>(Incoming);
if (!C || (CommonValue && C != CommonValue))
if (!C)
return 0;
// Fold the PHI's operands.
if (ConstantExpr *NewC = dyn_cast<ConstantExpr>(C))
C = ConstantFoldConstantExpression(NewC, TD, TLI);
// If the incoming value is a different constant to
// the one we saw previously, then give up.
if (CommonValue && C != CommonValue)
return 0;
CommonValue = C;
}
// If we reach here, all incoming values are the same constant or undef.
return CommonValue ? CommonValue : UndefValue::get(PN->getType());
}
@ -795,12 +802,18 @@ Constant *llvm::ConstantFoldInstruction(Instruction *I,
// Scan the operand list, checking to see if they are all constants, if so,
// hand off to ConstantFoldInstOperands.
SmallVector<Constant*, 8> Ops;
for (User::op_iterator i = I->op_begin(), e = I->op_end(); i != e; ++i)
if (Constant *Op = dyn_cast<Constant>(*i))
Ops.push_back(Op);
else
for (User::op_iterator i = I->op_begin(), e = I->op_end(); i != e; ++i) {
Constant *Op = dyn_cast<Constant>(*i);
if (!Op)
return 0; // All operands not constant!
// Fold the Instruction's operands.
if (ConstantExpr *NewCE = dyn_cast<ConstantExpr>(Op))
Op = ConstantFoldConstantExpression(NewCE, TD, TLI);
Ops.push_back(Op);
}
if (const CmpInst *CI = dyn_cast<CmpInst>(I))
return ConstantFoldCompareInstOperands(CI->getPredicate(), Ops[0], Ops[1],
TD, TLI);

View File

@ -55,13 +55,12 @@ static Constant *BitCastConstantVector(Constant *CV, VectorType *DstTy) {
Type *DstEltTy = DstTy->getElementType();
// Check to verify that all elements of the input are simple.
SmallVector<Constant*, 16> Result;
Type *Ty = IntegerType::get(CV->getContext(), 32);
for (unsigned i = 0; i != NumElts; ++i) {
Constant *C = CV->getAggregateElement(i);
if (C == 0) return 0;
Constant *C =
ConstantExpr::getExtractElement(CV, ConstantInt::get(Ty, i));
C = ConstantExpr::getBitCast(C, DstEltTy);
if (isa<ConstantExpr>(C)) return 0;
Result.push_back(C);
}
@ -553,9 +552,12 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, Constant *V,
SmallVector<Constant*, 16> res;
VectorType *DestVecTy = cast<VectorType>(DestTy);
Type *DstEltTy = DestVecTy->getElementType();
for (unsigned i = 0, e = V->getType()->getVectorNumElements(); i != e; ++i)
res.push_back(ConstantExpr::getCast(opc,
V->getAggregateElement(i), DstEltTy));
Type *Ty = IntegerType::get(V->getContext(), 32);
for (unsigned i = 0, e = V->getType()->getVectorNumElements(); i != e; ++i) {
Constant *C =
ConstantExpr::getExtractElement(V, ConstantInt::get(Ty, i));
res.push_back(ConstantExpr::getCast(opc, C, DstEltTy));
}
return ConstantVector::get(res);
}
@ -696,12 +698,13 @@ Constant *llvm::ConstantFoldSelectInstruction(Constant *Cond,
// If the condition is a vector constant, fold the result elementwise.
if (ConstantVector *CondV = dyn_cast<ConstantVector>(Cond)) {
SmallVector<Constant*, 16> Result;
Type *Ty = IntegerType::get(CondV->getContext(), 32);
for (unsigned i = 0, e = V1->getType()->getVectorNumElements(); i != e;++i){
ConstantInt *Cond = dyn_cast<ConstantInt>(CondV->getOperand(i));
if (Cond == 0) break;
Constant *Res = (Cond->getZExtValue() ? V1 : V2)->getAggregateElement(i);
if (Res == 0) break;
Constant *V = Cond->isNullValue() ? V2 : V1;
Constant *Res = ConstantExpr::getExtractElement(V, ConstantInt::get(Ty, i));
Result.push_back(Res);
}
@ -760,16 +763,16 @@ Constant *llvm::ConstantFoldInsertElementInstruction(Constant *Val,
const APInt &IdxVal = CIdx->getValue();
SmallVector<Constant*, 16> Result;
Type *Ty = IntegerType::get(Val->getContext(), 32);
for (unsigned i = 0, e = Val->getType()->getVectorNumElements(); i != e; ++i){
if (i == IdxVal) {
Result.push_back(Elt);
continue;
}
if (Constant *C = Val->getAggregateElement(i))
Result.push_back(C);
else
return 0;
Constant *C =
ConstantExpr::getExtractElement(Val, ConstantInt::get(Ty, i));
Result.push_back(C);
}
return ConstantVector::get(Result);
@ -801,11 +804,15 @@ Constant *llvm::ConstantFoldShuffleVectorInstruction(Constant *V1,
Constant *InElt;
if (unsigned(Elt) >= SrcNumElts*2)
InElt = UndefValue::get(EltTy);
else if (unsigned(Elt) >= SrcNumElts)
InElt = V2->getAggregateElement(Elt - SrcNumElts);
else
InElt = V1->getAggregateElement(Elt);
if (InElt == 0) return 0;
else if (unsigned(Elt) >= SrcNumElts) {
Type *Ty = IntegerType::get(V2->getContext(), 32);
InElt =
ConstantExpr::getExtractElement(V2,
ConstantInt::get(Ty, Elt - SrcNumElts));
} else {
Type *Ty = IntegerType::get(V1->getContext(), 32);
InElt = ConstantExpr::getExtractElement(V1, ConstantInt::get(Ty, Elt));
}
Result.push_back(InElt);
}
@ -1130,16 +1137,17 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode,
} else if (VectorType *VTy = dyn_cast<VectorType>(C1->getType())) {
// Perform elementwise folding.
SmallVector<Constant*, 16> Result;
Type *Ty = IntegerType::get(VTy->getContext(), 32);
for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) {
Constant *LHS = C1->getAggregateElement(i);
Constant *RHS = C2->getAggregateElement(i);
if (LHS == 0 || RHS == 0) break;
Constant *LHS =
ConstantExpr::getExtractElement(C1, ConstantInt::get(Ty, i));
Constant *RHS =
ConstantExpr::getExtractElement(C2, ConstantInt::get(Ty, i));
Result.push_back(ConstantExpr::get(Opcode, LHS, RHS));
}
if (Result.size() == VTy->getNumElements())
return ConstantVector::get(Result);
return ConstantVector::get(Result);
}
if (ConstantExpr *CE1 = dyn_cast<ConstantExpr>(C1)) {
@ -1697,17 +1705,18 @@ Constant *llvm::ConstantFoldCompareInstruction(unsigned short pred,
// If we can constant fold the comparison of each element, constant fold
// the whole vector comparison.
SmallVector<Constant*, 4> ResElts;
Type *Ty = IntegerType::get(C1->getContext(), 32);
// Compare the elements, producing an i1 result or constant expr.
for (unsigned i = 0, e = C1->getType()->getVectorNumElements(); i != e;++i){
Constant *C1E = C1->getAggregateElement(i);
Constant *C2E = C2->getAggregateElement(i);
if (C1E == 0 || C2E == 0) break;
Constant *C1E =
ConstantExpr::getExtractElement(C1, ConstantInt::get(Ty, i));
Constant *C2E =
ConstantExpr::getExtractElement(C2, ConstantInt::get(Ty, i));
ResElts.push_back(ConstantExpr::getCompare(pred, C1E, C2E));
}
if (ResElts.size() == C1->getType()->getVectorNumElements())
return ConstantVector::get(ResElts);
return ConstantVector::get(ResElts);
}
if (C1->getType()->isFloatingPointTy()) {

View File

@ -263,10 +263,10 @@ define i1* @hoo1() nounwind {
; OPT: ret i64 ptrtoint (double* getelementptr ({ i1, double }* null, i64 0, i32 1) to i64)
; OPT: }
; OPT: define i64 @fc() nounwind {
; OPT: ret i64 mul nuw (i64 ptrtoint (double* getelementptr (double* null, i32 1) to i64), i64 2)
; OPT: ret i64 mul (i64 ptrtoint (double* getelementptr (double* null, i32 1) to i64), i64 2)
; OPT: }
; OPT: define i64 @fd() nounwind {
; OPT: ret i64 mul nuw (i64 ptrtoint (double* getelementptr (double* null, i32 1) to i64), i64 11)
; OPT: ret i64 mul (i64 ptrtoint (double* getelementptr (double* null, i32 1) to i64), i64 11)
; OPT: }
; OPT: define i64 @fe() nounwind {
; OPT: ret i64 ptrtoint (double* getelementptr ({ double, float, double, double }* null, i64 0, i32 2) to i64)
@ -433,7 +433,7 @@ define i64* @fO() nounwind {
; PLAIN: ret i32* %t
; PLAIN: }
; OPT: define i32* @fZ() nounwind {
; OPT: ret i32* getelementptr inbounds (i32* getelementptr inbounds ([3 x { i32, i32 }]* @ext, i64 0, i64 1, i32 0), i64 1)
; OPT: ret i32* getelementptr (i32* getelementptr inbounds ([3 x { i32, i32 }]* @ext, i64 0, i64 1, i32 0), i64 1)
; OPT: }
; TO: define i32* @fZ() nounwind {
; TO: ret i32* getelementptr inbounds ([3 x { i32, i32 }]* @ext, i64 0, i64 1, i32 1)

View File

@ -620,3 +620,13 @@ end:
; CHECK-NOT: phi i32
; CHECK: ret i1 %z
}
; CHECK: @test27(
; CHECK: ret i32 undef
define i32 @test27(i1 %b) {
entry:
br label %done
done:
%y = phi i32 [ undef, %entry ]
ret i32 %y
}

View File

@ -0,0 +1,20 @@
; RUN: opt -sccp -S < %s | FileCheck %s
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128-n8:16:32-S128"
; CHECK: store volatile <2 x i64> zeroinitializer, <2 x i64>* %p
; rdar://11324230
define void @foo(<2 x i64>* %p) nounwind {
entry:
br label %while.body.i
while.body.i: ; preds = %while.body.i, %entry
%vWorkExponent.i.033 = phi <4 x i32> [ %sub.i.i, %while.body.i ], [ <i32 939524096, i32 939524096, i32 939524096, i32 939524096>, %entry ]
%sub.i.i = add <4 x i32> %vWorkExponent.i.033, <i32 -8388608, i32 -8388608, i32 -8388608, i32 -8388608>
%0 = bitcast <4 x i32> %sub.i.i to <2 x i64>
%and.i119.i = and <2 x i64> %0, zeroinitializer
store volatile <2 x i64> %and.i119.i, <2 x i64>* %p
br label %while.body.i
}