summaryrefslogtreecommitdiff
path: root/lib/Transforms/Scalar/PredicateSimplifier.cpp
diff options
context:
space:
mode:
authorNick Lewycky <nicholas@mxc.ca>2007-03-22 02:02:51 +0000
committerNick Lewycky <nicholas@mxc.ca>2007-03-22 02:02:51 +0000
commit27e4da93b6924879aabf941bc6c71d4299e92229 (patch)
treefcb50b51490d9cfba994ddd07684a3631991b8d6 /lib/Transforms/Scalar/PredicateSimplifier.cpp
parent67606125f64f0f90ca4f82c472c90355c656b4dc (diff)
downloadllvm-27e4da93b6924879aabf941bc6c71d4299e92229.tar.gz
llvm-27e4da93b6924879aabf941bc6c71d4299e92229.tar.bz2
llvm-27e4da93b6924879aabf941bc6c71d4299e92229.tar.xz
Fix broken optimization disabled by a logic bug.
Analyze GEPs. If the indices are all zero, transfer whether the pointer is known to be not null through the GEP. Add a few more cases for xor and shift instructions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@35257 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Scalar/PredicateSimplifier.cpp')
-rw-r--r--lib/Transforms/Scalar/PredicateSimplifier.cpp61
1 files changed, 51 insertions, 10 deletions
diff --git a/lib/Transforms/Scalar/PredicateSimplifier.cpp b/lib/Transforms/Scalar/PredicateSimplifier.cpp
index 072110642e..6ac309a8af 100644
--- a/lib/Transforms/Scalar/PredicateSimplifier.cpp
+++ b/lib/Transforms/Scalar/PredicateSimplifier.cpp
@@ -1516,13 +1516,27 @@ namespace {
add(SI->getCondition(), ConstantInt::getFalse(),
ICmpInst::ICMP_EQ, NewContext);
}
+ } else if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(I)) {
+ for (GetElementPtrInst::op_iterator OI = GEPI->idx_begin(),
+ OE = GEPI->idx_end(); OI != OE; ++OI) {
+ ConstantInt *Op = dyn_cast<ConstantInt>(IG.canonicalize(*OI, Top));
+ if (!Op || !Op->isZero()) return;
+ }
+ // TODO: The GEPI indices are all zero. Copy from definition to operand,
+ // jumping the type plane as needed.
+ if (isRelatedBy(GEPI, Constant::getNullValue(GEPI->getType()),
+ ICmpInst::ICMP_NE)) {
+ Value *Ptr = GEPI->getPointerOperand();
+ add(Ptr, Constant::getNullValue(Ptr->getType()), ICmpInst::ICMP_NE,
+ NewContext);
+ }
}
// TODO: CastInst "%a = cast ... %b" where %a is EQ or NE a constant.
}
/// opsToDef - A new relationship was discovered involving one of this
/// instruction's operands. Find any new relationship involving the
- /// definition.
+ /// definition, or another operand.
void opsToDef(Instruction *I) {
Instruction *NewContext = below(I) ? I : TopInst;
@@ -1551,6 +1565,9 @@ namespace {
switch (Opcode) {
default: break;
+ case Instruction::LShr:
+ case Instruction::AShr:
+ case Instruction::Shl:
case Instruction::Sub:
if (Op1 == Zero) {
add(BO, Op0, ICmpInst::ICMP_EQ, NewContext);
@@ -1562,6 +1579,7 @@ namespace {
add(BO, AllOnes, ICmpInst::ICMP_EQ, NewContext);
return;
} // fall-through
+ case Instruction::Xor:
case Instruction::Add:
if (Op0 == Zero) {
add(BO, Op1, ICmpInst::ICMP_EQ, NewContext);
@@ -1589,25 +1607,32 @@ namespace {
}
// "%x = add i32 %y, %z" and %x EQ %y then %z EQ 0
- // "%x = mul i32 %y, %z" and %x EQ %y then %z EQ 1
- // 1. Repeat all of the above, with order of operands reversed.
+ // "%x = add i32 %y, %z" and %x EQ %z then %y EQ 0
+ // "%x = shl i32 %y, %z" and %x EQ %y and %y NE 0 then %z EQ 0
// "%x = udiv i32 %y, %z" and %x EQ %y then %z EQ 1
- Value *Known = Op0, *Unknown = Op1;
- if (Known != BO) std::swap(Known, Unknown);
- if (Known == BO) {
+ Value *Known = Op0, *Unknown = Op1,
+ *TheBO = IG.canonicalize(BO, Top);
+ if (Known != TheBO) std::swap(Known, Unknown);
+ if (Known == TheBO) {
switch (Opcode) {
default: break;
+ case Instruction::LShr:
+ case Instruction::AShr:
+ case Instruction::Shl:
+ if (!isRelatedBy(Known, Zero, ICmpInst::ICMP_NE)) break;
+ // otherwise, fall-through.
+ case Instruction::Sub:
+ if (Unknown == Op1) break;
+ // otherwise, fall-through.
case Instruction::Xor:
case Instruction::Add:
- case Instruction::Sub:
add(Unknown, Zero, ICmpInst::ICMP_EQ, NewContext);
break;
case Instruction::UDiv:
case Instruction::SDiv:
- if (Unknown == Op0) break; // otherwise, fallthrough
- case Instruction::Mul:
- if (isa<ConstantInt>(Unknown)) {
+ if (Unknown == Op1) break;
+ if (isRelatedBy(Known, Zero, ICmpInst::ICMP_NE)) {
Constant *One = ConstantInt::get(Ty, 1);
add(Unknown, One, ICmpInst::ICMP_EQ, NewContext);
}
@@ -1633,6 +1658,8 @@ namespace {
}
} else if (SelectInst *SI = dyn_cast<SelectInst>(I)) {
+ if (I->getType()->isFPOrFPVector()) return;
+
// Given: "%a = select i1 %x, i32 %b, i32 %c"
// %x EQ true then %a EQ %b
// %x EQ false then %a EQ %c
@@ -1658,6 +1685,20 @@ namespace {
}
// TODO: "%a = cast ... %b" where %b is NE/LT/GT a constant.
+ } else if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(I)) {
+ for (GetElementPtrInst::op_iterator OI = GEPI->idx_begin(),
+ OE = GEPI->idx_end(); OI != OE; ++OI) {
+ ConstantInt *Op = dyn_cast<ConstantInt>(IG.canonicalize(*OI, Top));
+ if (!Op || !Op->isZero()) return;
+ }
+ // TODO: The GEPI indices are all zero. Copy from operand to definition,
+ // jumping the type plane as needed.
+ Value *Ptr = GEPI->getPointerOperand();
+ if (isRelatedBy(Ptr, Constant::getNullValue(Ptr->getType()),
+ ICmpInst::ICMP_NE)) {
+ add(GEPI, Constant::getNullValue(GEPI->getType()), ICmpInst::ICMP_NE,
+ NewContext);
+ }
}
}