summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2016-03-03 19:19:04 +0000
committerSanjay Patel <spatel@rotateright.com>2016-03-03 19:19:04 +0000
commit9bba75084b7bde6a6215d616f664d3d2486f4871 (patch)
tree8be3639147b06fb4a8e05435d20886eb75516436 /llvm/lib/Transforms
parentdd12e9a8c04eb1cc5b43df4d249273678c5fec6b (diff)
downloadbcm5719-llvm-9bba75084b7bde6a6215d616f664d3d2486f4871.tar.gz
bcm5719-llvm-9bba75084b7bde6a6215d616f664d3d2486f4871.zip
[InstCombine] transform bitcasted bitwise logic ops with constants (PR26702)
Given that we're not actually reducing the instruction count in the included regression tests, I think we would call this a canonicalization step. The motivation comes from the example in PR26702: https://llvm.org/bugs/show_bug.cgi?id=26702 If we hoist the bitwise logic ahead of the bitcast, the previously unoptimizable example of: define <4 x i32> @is_negative(<4 x i32> %x) { %lobit = ashr <4 x i32> %x, <i32 31, i32 31, i32 31, i32 31> %not = xor <4 x i32> %lobit, <i32 -1, i32 -1, i32 -1, i32 -1> %bc = bitcast <4 x i32> %not to <2 x i64> %notnot = xor <2 x i64> %bc, <i64 -1, i64 -1> %bc2 = bitcast <2 x i64> %notnot to <4 x i32> ret <4 x i32> %bc2 } Simplifies to the expected: define <4 x i32> @is_negative(<4 x i32> %x) { %lobit = ashr <4 x i32> %x, <i32 31, i32 31, i32 31, i32 31> ret <4 x i32> %lobit } Differential Revision: http://reviews.llvm.org/D17583 llvm-svn: 262645
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp35
1 files changed, 28 insertions, 7 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index d19a0226fbc..4a6e99c3cdb 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -1251,21 +1251,42 @@ Instruction *InstCombiner::foldCastedBitwiseLogic(BinaryOperator &I) {
Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
CastInst *Cast0 = dyn_cast<CastInst>(Op0);
+ if (!Cast0)
+ return nullptr;
+
+ // This must be a cast from an integer or integer vector source type to allow
+ // transformation of the logic operation to the source type.
+ Type *DestTy = I.getType();
+ Type *SrcTy = Cast0->getSrcTy();
+ if (!SrcTy->isIntOrIntVectorTy())
+ return nullptr;
+
+ // If one operand is a bitcast and the other is a constant, move the logic
+ // operation ahead of the bitcast. That is, do the logic operation in the
+ // original type. This can eliminate useless bitcasts and allow normal
+ // combines that would otherwise be impeded by the bitcast. Canonicalization
+ // ensures that if there is a constant operand, it will be the second operand.
+ Value *BC = nullptr;
+ Constant *C = nullptr;
+ if ((match(Op0, m_BitCast(m_Value(BC))) && match(Op1, m_Constant(C)))) {
+ // A bitcast of a constant will be removed.
+ Value *NewConstant = Builder->CreateBitCast(C, SrcTy);
+ Value *NewOp = Builder->CreateBinOp(LogicOpc, BC, NewConstant, I.getName());
+ return CastInst::CreateBitOrPointerCast(NewOp, DestTy);
+ }
+
CastInst *Cast1 = dyn_cast<CastInst>(Op1);
- if (!Cast0 || !Cast1)
+ if (!Cast1)
return nullptr;
- // The casts must be of the same type, and this must be a cast from an integer
- // or integer vector source type.
+ // Both operands of the logic operation are casts. The casts must be of the
+ // same type for reduction.
auto CastOpcode = Cast0->getOpcode();
- Type *SrcTy = Cast0->getSrcTy();
- if ((CastOpcode != Cast1->getOpcode()) || (SrcTy != Cast1->getSrcTy()) ||
- !SrcTy->isIntOrIntVectorTy())
+ if (CastOpcode != Cast1->getOpcode() || SrcTy != Cast1->getSrcTy())
return nullptr;
Value *Cast0Src = Cast0->getOperand(0);
Value *Cast1Src = Cast1->getOperand(0);
- Type *DestTy = I.getType();
// fold (logic (cast A), (cast B)) -> (cast (logic A, B))
OpenPOWER on IntegriCloud