aboutsummaryrefslogtreecommitdiff
path: root/lib/Transforms
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2005-05-04 19:10:26 +0000
committerChris Lattner <sabre@nondot.org>2005-05-04 19:10:26 +0000
commit693787a5ec14eb523a9c4a7653a34f1ff7df7f3e (patch)
treefe250362fa305577b9593b3704592c80d9998e53 /lib/Transforms
parent3a9a7701f0f935cf2db5aab11ac4b42a686cefe5 (diff)
Instcombine: cast (X != 0) to int, cast (X == 1) to int -> X iff X has only the low bit set.
This implements set.ll:test20. This triggers 2x on povray, 9x on mesa, 11x on gcc, 2x on crafty, 1x on eon, 6x on perlbmk and 11x on m88ksim. It allows us to compile these two functions into the same code: struct s { unsigned int bit : 1; }; unsigned foo(struct s *p) { if (p->bit) return 1; else return 0; } unsigned bar(struct s *p) { return p->bit; } git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@21690 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms')
-rw-r--r--lib/Transforms/Scalar/InstructionCombining.cpp28
1 files changed, 25 insertions, 3 deletions
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp
index 5fe95540de..fa615cfc51 100644
--- a/lib/Transforms/Scalar/InstructionCombining.cpp
+++ b/lib/Transforms/Scalar/InstructionCombining.cpp
@@ -3553,9 +3553,30 @@ Instruction *InstCombiner::visitCastInst(CastInst &CI) {
return new ShiftInst(Instruction::Shl, Op0c, Op1);
}
break;
+ case Instruction::SetNE:
+ case Instruction::SetEQ:
+ // We if we are just checking for a seteq of a single bit and casting it
+ // to an integer. If so, shift the bit to the appropriate place then
+ // cast to integer to avoid the comparison.
+ if (ConstantInt *Op1C = dyn_cast<ConstantInt>(Op1)) {
+ // cast (X != 0) to int, cast (X == 1) to int -> X iff X has only the
+ // low bit set.
+ bool isSetNE = SrcI->getOpcode() == Instruction::SetNE;
+ if ((isSetNE && Op1C->getRawValue() == 0) ||
+ (!isSetNE && Op1C->getRawValue() == 1)) {
+ Constant *Not1 =
+ ConstantExpr::getNot(ConstantInt::get(Op0->getType(), 1));
+ if (MaskedValueIsZero(Op0, cast<ConstantIntegral>(Not1))) {
+ if (CI.getType() == Op0->getType())
+ return ReplaceInstUsesWith(CI, Op0);
+ else
+ return new CastInst(Op0, CI.getType());
+ }
+ }
+ }
+ break;
}
}
-
return 0;
}
@@ -4603,8 +4624,9 @@ Instruction *InstCombiner::visitAllocationInst(AllocationInst &AI) {
// Now that I is pointing to the first non-allocation-inst in the block,
// insert our getelementptr instruction...
//
- std::vector<Value*> Idx(2, Constant::getNullValue(Type::IntTy));
- Value *V = new GetElementPtrInst(New, Idx, New->getName()+".sub", It);
+ Value *NullIdx = Constant::getNullValue(Type::IntTy);
+ Value *V = new GetElementPtrInst(New, NullIdx, NullIdx,
+ New->getName()+".sub", It);
// Now make everything use the getelementptr instead of the original
// allocation.