[llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
Chris Lattner
lattner at cs.uiuc.edu
Sat Oct 16 11:11:48 PDT 2004
Changes in directory llvm/lib/Transforms/Scalar:
InstructionCombining.cpp updated: 1.267 -> 1.268
---
Log message:
Optimize instructions involving undef values. For example X+undef == undef.
---
Diffs of the changes: (+126 -28)
Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.267 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.268
--- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.267 Mon Oct 11 23:52:52 2004
+++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Sat Oct 16 13:11:37 2004
@@ -121,6 +121,7 @@
Instruction *visitAllocationInst(AllocationInst &AI);
Instruction *visitFreeInst(FreeInst &FI);
Instruction *visitLoadInst(LoadInst &LI);
+ Instruction *visitStoreInst(StoreInst &SI);
Instruction *visitBranchInst(BranchInst &BI);
Instruction *visitSwitchInst(SwitchInst &SI);
@@ -216,15 +217,15 @@
}
// getComplexity: Assign a complexity or rank value to LLVM Values...
-// 0 -> Constant, 1 -> Other, 2 -> Argument, 2 -> Unary, 3 -> OtherInst
+// 0 -> undef, 1 -> Const, 2 -> Other, 3 -> Arg, 3 -> Unary, 4 -> OtherInst
static unsigned getComplexity(Value *V) {
if (isa<Instruction>(V)) {
if (BinaryOperator::isNeg(V) || BinaryOperator::isNot(V))
- return 2;
- return 3;
+ return 3;
+ return 4;
}
- if (isa<Argument>(V)) return 2;
- return isa<Constant>(V) ? 0 : 1;
+ if (isa<Argument>(V)) return 3;
+ return isa<Constant>(V) ? (isa<UndefValue>(V) ? 0 : 1) : 2;
}
// isOnlyUse - Return true if this instruction will be deleted if we stop using
@@ -559,6 +560,10 @@
Value *LHS = I.getOperand(0), *RHS = I.getOperand(1);
if (Constant *RHSC = dyn_cast<Constant>(RHS)) {
+ // X + undef -> undef
+ if (isa<UndefValue>(RHS))
+ return ReplaceInstUsesWith(I, RHS);
+
// X + 0 --> X
if (!I.getType()->isFloatingPoint() && // -0 + +0 = +0, so it's not a noop
RHSC->isNullValue())
@@ -691,6 +696,11 @@
if (Value *V = dyn_castNegVal(Op1))
return BinaryOperator::createAdd(Op0, V);
+ if (isa<UndefValue>(Op0))
+ return ReplaceInstUsesWith(I, Op0); // undef - X -> undef
+ if (isa<UndefValue>(Op1))
+ return ReplaceInstUsesWith(I, Op1); // X - undef -> undef
+
if (ConstantInt *C = dyn_cast<ConstantInt>(Op0)) {
// Replace (-1 - A) with (~A)...
if (C->isAllOnesValue())
@@ -823,6 +833,9 @@
bool Changed = SimplifyCommutative(I);
Value *Op0 = I.getOperand(0);
+ if (isa<UndefValue>(I.getOperand(1))) // undef * X -> 0
+ return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
+
// Simplify mul instructions with a constant RHS...
if (Constant *Op1 = dyn_cast<Constant>(I.getOperand(1))) {
if (ConstantInt *CI = dyn_cast<ConstantInt>(Op1)) {
@@ -919,6 +932,11 @@
}
Instruction *InstCombiner::visitDiv(BinaryOperator &I) {
+ if (isa<UndefValue>(I.getOperand(0))) // undef / X -> 0
+ return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
+ if (isa<UndefValue>(I.getOperand(1)))
+ return ReplaceInstUsesWith(I, I.getOperand(1)); // X / undef -> undef
+
if (ConstantInt *RHS = dyn_cast<ConstantInt>(I.getOperand(1))) {
// div X, 1 == X
if (RHS->equalsInt(1))
@@ -974,6 +992,11 @@
return &I;
}
+ if (isa<UndefValue>(I.getOperand(0))) // undef % X -> 0
+ return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
+ if (isa<UndefValue>(I.getOperand(1)))
+ return ReplaceInstUsesWith(I, I.getOperand(1)); // X % undef -> undef
+
if (ConstantInt *RHS = dyn_cast<ConstantInt>(I.getOperand(1))) {
if (RHS->equalsInt(1)) // X % 1 == 0
return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
@@ -1331,6 +1354,9 @@
bool Changed = SimplifyCommutative(I);
Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
+ if (isa<UndefValue>(Op1)) // X & undef -> 0
+ return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
+
// and X, X = X and X, 0 == 0
if (Op0 == Op1 || Op1 == Constant::getNullValue(I.getType()))
return ReplaceInstUsesWith(I, Op1);
@@ -1475,6 +1501,10 @@
bool Changed = SimplifyCommutative(I);
Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
+ if (isa<UndefValue>(Op1))
+ return ReplaceInstUsesWith(I, // X | undef -> -1
+ ConstantIntegral::getAllOnesValue(I.getType()));
+
// or X, X = X or X, 0 == X
if (Op0 == Op1 || Op1 == Constant::getNullValue(I.getType()))
return ReplaceInstUsesWith(I, Op0);
@@ -1652,6 +1682,9 @@
bool Changed = SimplifyCommutative(I);
Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
+ if (isa<UndefValue>(Op1))
+ return ReplaceInstUsesWith(I, Op1); // X ^ undef -> undef
+
// xor X, X = 0, even if X is nested in a sequence of Xor's.
if (Instruction *Result = AssociativeOpt(I, XorSelf(Op1))) {
assert(Result == &I && "AssociativeOpt didn't work?");
@@ -1823,6 +1856,9 @@
if (Op0 == Op1)
return ReplaceInstUsesWith(I, ConstantBool::get(isTrueWhenEqual(I)));
+ if (isa<UndefValue>(Op1)) // X setcc undef -> undef
+ return ReplaceInstUsesWith(I, UndefValue::get(Type::BoolTy));
+
// setcc <global/alloca*>, 0 - Global/Stack value addresses are never null!
if (isa<ConstantPointerNull>(Op1) &&
(isa<GlobalValue>(Op0) || isa<AllocaInst>(Op0)))
@@ -2478,6 +2514,19 @@
Op0 == Constant::getNullValue(Op0->getType()))
return ReplaceInstUsesWith(I, Op0);
+ if (isa<UndefValue>(Op0)) { // undef >>s X -> undef
+ if (!isLeftShift && I.getType()->isSigned())
+ return ReplaceInstUsesWith(I, Op1);
+ else // undef << X -> 0 AND undef >>u X -> 0
+ return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
+ }
+ if (isa<UndefValue>(Op1)) {
+ if (isLeftShift || I.getType()->isUnsigned())
+ return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
+ else
+ return ReplaceInstUsesWith(I, Op0); // X >>s undef -> X
+ }
+
// shr int -1, X = -1 (for any arithmetic shift rights of ~0)
if (!isLeftShift)
if (ConstantSInt *CSI = dyn_cast<ConstantSInt>(Op0))
@@ -2736,6 +2785,9 @@
if (CI.getType() == Src->getType())
return ReplaceInstUsesWith(CI, Src);
+ if (isa<UndefValue>(Src)) // cast undef -> undef
+ return ReplaceInstUsesWith(CI, UndefValue::get(CI.getType()));
+
// If casting the result of another cast instruction, try to eliminate this
// one!
//
@@ -2935,6 +2987,17 @@
if (TrueVal == FalseVal)
return ReplaceInstUsesWith(SI, TrueVal);
+ if (isa<UndefValue>(TrueVal)) // select C, undef, X -> X
+ return ReplaceInstUsesWith(SI, FalseVal);
+ if (isa<UndefValue>(FalseVal)) // select C, X, undef -> X
+ return ReplaceInstUsesWith(SI, TrueVal);
+ if (isa<UndefValue>(CondVal)) { // select undef, X, Y -> X or Y
+ if (isa<Constant>(TrueVal))
+ return ReplaceInstUsesWith(SI, TrueVal);
+ else
+ return ReplaceInstUsesWith(SI, FalseVal);
+ }
+
if (SI.getType() == Type::BoolTy)
if (ConstantBool *C = dyn_cast<ConstantBool>(TrueVal)) {
if (C == ConstantBool::True) {
@@ -3092,7 +3155,6 @@
// CallInst simplification
//
Instruction *InstCombiner::visitCallInst(CallInst &CI) {
-
// Intrinsics cannot occur in an invoke, so handle them here instead of in
// visitCallSite.
if (MemIntrinsic *MI = dyn_cast<MemIntrinsic>(&CI)) {
@@ -3147,6 +3209,17 @@
if (transformConstExprCastCall(CS)) return 0;
Value *Callee = CS.getCalledValue();
+
+ if (isa<ConstantPointerNull>(Callee) || isa<UndefValue>(Callee))
+ // This instruction is not reachable, just remove it. Eventually, this
+ // should get turned into an unreachable instruction.
+ if (!isa<InvokeInst>(CS.getInstruction())) { // Don't hack the CFG!
+ if (!CS.getInstruction()->use_empty())
+ CS.getInstruction()->
+ replaceAllUsesWith(UndefValue::get(CS.getInstruction()->getType()));
+ return EraseInstFromFunction(*CS.getInstruction());
+ }
+
const PointerType *PTy = cast<PointerType>(Callee->getType());
const FunctionType *FTy = cast<FunctionType>(PTy->getElementType());
if (FTy->isVarArg()) {
@@ -3307,6 +3380,7 @@
// PHINode simplification
//
Instruction *InstCombiner::visitPHINode(PHINode &PN) {
+ // FIXME: hasConstantValue should ignore undef values!
if (Value *V = hasConstantValue(&PN))
return ReplaceInstUsesWith(PN, V);
@@ -3363,6 +3437,9 @@
if (GEP.getNumOperands() == 1)
return ReplaceInstUsesWith(GEP, PtrOp);
+ if (isa<UndefValue>(GEP.getOperand(0)))
+ return ReplaceInstUsesWith(GEP, UndefValue::get(GEP.getType()));
+
bool HasZeroPointerIndex = false;
if (Constant *C = dyn_cast<Constant>(GEP.getOperand(1)))
HasZeroPointerIndex = C->isNullValue();
@@ -3601,6 +3678,8 @@
// Now make everything use the getelementptr instead of the original
// allocation.
return ReplaceInstUsesWith(AI, V);
+ } else if (isa<UndefValue>(AI.getArraySize())) {
+ return ReplaceInstUsesWith(AI, Constant::getNullValue(AI.getType()));
}
// If alloca'ing a zero byte object, replace the alloca with a null pointer.
@@ -3625,7 +3704,8 @@
// If we have 'free null' delete the instruction. This can happen in stl code
// when lots of inlining happens.
- if (isa<ConstantPointerNull>(Op))
+ // FIXME: free undef should be xformed into an 'unreachable' instruction.
+ if (isa<ConstantPointerNull>(Op) || isa<UndefValue>(Op))
return EraseInstFromFunction(FI);
return 0;
@@ -3652,6 +3732,8 @@
C = CS->getOperand(CU->getValue());
} else if (isa<ConstantAggregateZero>(C)) {
C = Constant::getNullValue(STy->getElementType(CU->getValue()));
+ } else if (isa<UndefValue>(C)) {
+ C = UndefValue::get(STy->getElementType(CU->getValue()));
} else {
return 0;
}
@@ -3662,6 +3744,8 @@
C = CA->getOperand(CI->getRawValue());
else if (isa<ConstantAggregateZero>(C))
C = Constant::getNullValue(ATy->getElementType());
+ else if (isa<UndefValue>(C))
+ C = UndefValue::get(ATy->getElementType());
else
return 0;
} else {
@@ -3725,26 +3809,29 @@
Instruction *InstCombiner::visitLoadInst(LoadInst &LI) {
Value *Op = LI.getOperand(0);
- if (Constant *C = dyn_cast<Constant>(Op))
- if (C->isNullValue() && !LI.isVolatile()) // load null -> 0
- return ReplaceInstUsesWith(LI, Constant::getNullValue(LI.getType()));
-
- // Instcombine load (constant global) into the value loaded...
- if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Op))
- if (GV->isConstant() && !GV->isExternal())
- return ReplaceInstUsesWith(LI, GV->getInitializer());
-
- // Instcombine load (constantexpr_GEP global, 0, ...) into the value loaded...
- if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Op))
- if (CE->getOpcode() == Instruction::GetElementPtr) {
- if (GlobalVariable *GV = dyn_cast<GlobalVariable>(CE->getOperand(0)))
- if (GV->isConstant() && !GV->isExternal())
- if (Constant *V = GetGEPGlobalInitializer(GV->getInitializer(), CE))
- return ReplaceInstUsesWith(LI, V);
- } else if (CE->getOpcode() == Instruction::Cast) {
- if (Instruction *Res = InstCombineLoadCast(*this, LI))
- return Res;
- }
+ if (Constant *C = dyn_cast<Constant>(Op)) {
+ if ((C->isNullValue() || isa<UndefValue>(C)) &&
+ !LI.isVolatile()) // load null -> undef
+ // FIXME: this should become an unreachable instruction
+ return ReplaceInstUsesWith(LI, UndefValue::get(LI.getType()));
+
+ // Instcombine load (constant global) into the value loaded.
+ if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Op))
+ if (GV->isConstant() && !GV->isExternal())
+ return ReplaceInstUsesWith(LI, GV->getInitializer());
+
+ // Instcombine load (constantexpr_GEP global, 0, ...) into the value loaded.
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Op))
+ if (CE->getOpcode() == Instruction::GetElementPtr) {
+ if (GlobalVariable *GV = dyn_cast<GlobalVariable>(CE->getOperand(0)))
+ if (GV->isConstant() && !GV->isExternal())
+ if (Constant *V = GetGEPGlobalInitializer(GV->getInitializer(), CE))
+ return ReplaceInstUsesWith(LI, V);
+ } else if (CE->getOpcode() == Instruction::Cast) {
+ if (Instruction *Res = InstCombineLoadCast(*this, LI))
+ return Res;
+ }
+ }
// load (cast X) --> cast (load X) iff safe
if (CastInst *CI = dyn_cast<CastInst>(Op))
@@ -3832,6 +3919,17 @@
return 0;
}
+Instruction *InstCombiner::visitStoreInst(StoreInst &SI) {
+ if (isa<ConstantPointerNull>(SI.getOperand(1)) ||
+ isa<UndefValue>(SI.getOperand(1))) {
+ // FIXME: This should become an unreachable instruction.
+ return EraseInstFromFunction(SI);
+ }
+
+
+ return 0;
+}
+
Instruction *InstCombiner::visitBranchInst(BranchInst &BI) {
// Change br (not X), label True, label False to: br X, label False, True
@@ -3877,7 +3975,7 @@
if (ConstantInt *AddRHS = dyn_cast<ConstantInt>(I->getOperand(1))) {
// change 'switch (X+4) case 1:' into 'switch (X) case -3'
for (unsigned i = 2, e = SI.getNumOperands(); i != e; i += 2)
- SI.setOperand(i, ConstantExpr::getSub(cast<Constant>(SI.getOperand(i)),
+ SI.setOperand(i,ConstantExpr::getSub(cast<Constant>(SI.getOperand(i)),
AddRHS));
SI.setOperand(0, I->getOperand(0));
WorkList.push_back(I);
More information about the llvm-commits
mailing list