aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Transforms/Scalar
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2003-07-22 21:46:59 +0000
committerChris Lattner <sabre@nondot.org>2003-07-22 21:46:59 +0000
commit1ba5bcd1ae23805b41e28d3cf62a11b18b465348 (patch)
tree3118f243b8a65d7369909632aab71ce87a6a7098 /lib/Transforms/Scalar
parenta73fede7143911085186458d8b28d52cfb26396c (diff)
downloadexternal_llvm-1ba5bcd1ae23805b41e28d3cf62a11b18b465348.zip
external_llvm-1ba5bcd1ae23805b41e28d3cf62a11b18b465348.tar.gz
external_llvm-1ba5bcd1ae23805b41e28d3cf62a11b18b465348.tar.bz2
- InstCombine (cast (xor A, B) to bool) ==> (setne A, B)
- InstCombine (cast (and X, (1 << size(X)-1)) to bool) ==> x < 0 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@7241 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Scalar')
-rw-r--r--lib/Transforms/Scalar/InstructionCombining.cpp49
1 files changed, 44 insertions, 5 deletions
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp
index b066dec..0ecec73 100644
--- a/lib/Transforms/Scalar/InstructionCombining.cpp
+++ b/lib/Transforms/Scalar/InstructionCombining.cpp
@@ -291,6 +291,13 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) {
return Changed ? &I : 0;
}
+// isSignBit - Return true if the value represented by the constant only has the
+// highest order bit set.
+static bool isSignBit(ConstantInt *CI) {
+ unsigned NumBits = CI->getType()->getPrimitiveSize()*8;
+ return (CI->getRawValue() & ~(-1LL << NumBits)) == (1ULL << (NumBits-1));
+}
+
Instruction *InstCombiner::visitSub(BinaryOperator &I) {
Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
@@ -959,13 +966,15 @@ Instruction *InstCombiner::visitCastInst(CastInst &CI) {
if (BinaryOperator *BO = dyn_cast<BinaryOperator>(Src)) {
Value *Op0 = BO->getOperand(0), *Op1 = BO->getOperand(1);
- // Replace (cast (sub A, B) to bool) with (setne A, B)
- if (BO->getOpcode() == Instruction::Sub)
+ switch (BO->getOpcode()) {
+ case Instruction::Sub:
+ case Instruction::Xor:
+ // Replace (cast ([sub|xor] A, B) to bool) with (setne A, B)
return new SetCondInst(Instruction::SetNE, Op0, Op1);
// Replace (cast (add A, B) to bool) with (setne A, -B) if B is
// efficiently invertible, or if the add has just this one use.
- if (BO->getOpcode() == Instruction::Add)
+ case Instruction::Add:
if (Value *NegVal = dyn_castNegVal(Op1))
return new SetCondInst(Instruction::SetNE, Op0, NegVal);
else if (Value *NegVal = dyn_castNegVal(Op0))
@@ -976,6 +985,36 @@ Instruction *InstCombiner::visitCastInst(CastInst &CI) {
InsertNewInstBefore(Neg, CI);
return new SetCondInst(Instruction::SetNE, Op0, Neg);
}
+ break;
+
+ case Instruction::And:
+ // Replace (cast (and X, (1 << size(X)-1)) to bool) with x < 0,
+ // converting X to be a signed value as appropriate. Don't worry about
+ // bool values, as they will be optimized other ways if they occur in
+ // this configuration.
+ if (ConstantInt *CInt = dyn_cast<ConstantInt>(Op1))
+ if (isSignBit(CInt)) {
+ // If 'X' is not signed, insert a cast now...
+ if (!CInt->getType()->isSigned()) {
+ const Type *DestTy;
+ switch (CInt->getType()->getPrimitiveID()) {
+ case Type::UByteTyID: DestTy = Type::SByteTy; break;
+ case Type::UShortTyID: DestTy = Type::ShortTy; break;
+ case Type::UIntTyID: DestTy = Type::IntTy; break;
+ case Type::ULongTyID: DestTy = Type::LongTy; break;
+ default: assert(0 && "Invalid unsigned integer type!"); abort();
+ }
+ CastInst *NewCI = new CastInst(Op0, DestTy,
+ Op0->getName()+".signed");
+ InsertNewInstBefore(NewCI, CI);
+ Op0 = NewCI;
+ }
+ return new SetCondInst(Instruction::SetLT, Op0,
+ Constant::getNullValue(Op0->getType()));
+ }
+ break;
+ default: break;
+ }
}
}
@@ -1294,7 +1333,7 @@ Instruction *InstCombiner::visitLoadInst(LoadInst &LI) {
// Instcombine load (constant global) into the value loaded...
if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Op))
- if ((GV->isConstant()) && (!(GV->isExternal())))
+ if (GV->isConstant() && !GV->isExternal())
return ReplaceInstUsesWith(LI, GV->getInitializer());
// Instcombine load (constantexpr_GEP global, 0, ...) into the value loaded...
@@ -1302,7 +1341,7 @@ Instruction *InstCombiner::visitLoadInst(LoadInst &LI) {
if (CE->getOpcode() == Instruction::GetElementPtr)
if (ConstantPointerRef *G=dyn_cast<ConstantPointerRef>(CE->getOperand(0)))
if (GlobalVariable *GV = dyn_cast<GlobalVariable>(G->getValue()))
- if ((GV->isConstant()) && (!(GV->isExternal())))
+ if (GV->isConstant() && !GV->isExternal())
if (Constant *V = GetGEPGlobalInitializer(GV->getInitializer(), CE))
return ReplaceInstUsesWith(LI, V);
return 0;