summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorRoman Lebedev <lebedev.ri@gmail.com>2019-10-04 22:16:11 +0000
committerRoman Lebedev <lebedev.ri@gmail.com>2019-10-04 22:16:11 +0000
commitf304d4d185d24eec9f0ca84d566da0d51b2344ef (patch)
tree515be38bbf0d6a835b9600b54647ebd0bfd63912 /llvm/lib
parentae738641d53e06b30b1189aedaa1c3dddd8d371d (diff)
downloadbcm5719-llvm-f304d4d185d24eec9f0ca84d566da0d51b2344ef.tar.gz
bcm5719-llvm-f304d4d185d24eec9f0ca84d566da0d51b2344ef.zip
[InstCombine] Right-shift shift amount reassociation with truncation (PR43564, PR42391)
Initially (D65380) i believed that if we have rightshift-trunc-rightshift, we can't do any folding. But as it usually happens, i was wrong. https://rise4fun.com/Alive/GEw https://rise4fun.com/Alive/gN2O In https://bugs.llvm.org/show_bug.cgi?id=43564 we happen to have this very sequence, of two right shifts separated by trunc. And "just" so that happens, we apparently can fold the pattern if the total shift amount is either 0, or it's equal to the bitwidth of the innermost widest shift - i.e. if we are left with only the original sign bit. Which is exactly what is wanted there. llvm-svn: 373801
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp34
1 files changed, 19 insertions, 15 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
index 9d96ddc4040..8ab4aeb38be 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
@@ -61,16 +61,10 @@ reassociateShiftAmtsOfTwoSameDirectionShifts(BinaryOperator *Sh0,
if (ShiftOpcode != Sh1->getOpcode())
return nullptr;
- // Did we match a pattern with truncation ?
- if (Trunc) {
- // For right-shifts we can't do any such simplifications. Leave as-is.
- if (ShiftOpcode != Instruction::BinaryOps::Shl)
- return nullptr; // FIXME: still could perform constant-folding.
- // If we saw truncation, we'll need to produce extra instruction,
- // and for that one of the operands of the shift must be one-use.
- if (!match(Sh0, m_c_BinOp(m_OneUse(m_Value()), m_Value())))
- return nullptr;
- }
+ // If we saw truncation, we'll need to produce extra instruction,
+ // and for that one of the operands of the shift must be one-use.
+ if (Trunc && !match(Sh0, m_c_BinOp(m_OneUse(m_Value()), m_Value())))
+ return nullptr;
// Can we fold (ShAmt0+ShAmt1) ?
auto *NewShAmt = dyn_cast_or_null<Constant>(
@@ -78,13 +72,23 @@ reassociateShiftAmtsOfTwoSameDirectionShifts(BinaryOperator *Sh0,
SQ.getWithInstruction(Sh0)));
if (!NewShAmt)
return nullptr; // Did not simplify.
- // Is the new shift amount smaller than the bit width of inner shift?
- if (!match(NewShAmt, m_SpecificInt_ICMP(
- ICmpInst::Predicate::ICMP_ULT,
- APInt(NewShAmt->getType()->getScalarSizeInBits(),
- X->getType()->getScalarSizeInBits()))))
+ unsigned NewShAmtBitWidth = NewShAmt->getType()->getScalarSizeInBits();
+ unsigned XBitWidth = X->getType()->getScalarSizeInBits();
+ // Is the new shift amount smaller than the bit width of inner/new shift?
+ if (!match(NewShAmt, m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULT,
+ APInt(NewShAmtBitWidth, XBitWidth))))
return nullptr; // FIXME: could perform constant-folding.
+ // If there was a truncation, and we have a right-shift, we can only fold if
+ // we are left with the original sign bit.
+ // FIXME: zero shift amount is also legal here, but we can't *easily* check
+ // more than one predicate so it's not really worth it.
+ if (Trunc && ShiftOpcode != Instruction::BinaryOps::Shl &&
+ !match(NewShAmt,
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_EQ,
+ APInt(NewShAmtBitWidth, XBitWidth - 1))))
+ return nullptr;
+
// All good, we can do this fold.
NewShAmt = ConstantExpr::getZExtOrBitCast(NewShAmt, X->getType());
OpenPOWER on IntegriCloud