[llvm] r317518 - Revert r317510 "[InstCombine] Pull shifts through a select plus binop with constant"
Hans Wennborg via llvm-commits
llvm-commits at lists.llvm.org
Mon Nov 6 14:28:02 PST 2017
Author: hans
Date: Mon Nov 6 14:28:02 2017
New Revision: 317518
URL: http://llvm.org/viewvc/llvm-project?rev=317518&view=rev
Log:
Revert r317510 "[InstCombine] Pull shifts through a select plus binop with constant"
This broke the CodeGen/Hexagon/loop-idiom/pmpy-mod.ll test on a bunch of buildbots.
> This pulls shifts through a select+binop with a constant where the select conditionally executes the binop. We already do this for just the binop, but not with the select.
>
> This can allow us to get the select closer to other selects to enable removing one.
>
> Differential Revision: https://reviews.llvm.org/D39222
>
> git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@317510 91177308-0d34-0410-b5e6-96231b3b80d8
Modified:
llvm/trunk/lib/Transforms/InstCombine/InstCombineShifts.cpp
llvm/trunk/test/Transforms/InstCombine/shift.ll
Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineShifts.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineShifts.cpp?rev=317518&r1=317517&r2=317518&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineShifts.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineShifts.cpp Mon Nov 6 14:28:02 2017
@@ -310,40 +310,6 @@ static Value *getShiftedValue(Value *V,
}
}
-// If this is a bitwise operator or add with a constant RHS we might be able
-// to pull it through a shift.
-static bool canShiftBinOpWithConstantRHS(BinaryOperator &Shift,
- BinaryOperator *BO,
- const APInt &C) {
- bool IsValid = true; // Valid only for And, Or Xor,
- bool HighBitSet = false; // Transform ifhigh bit of constant set?
-
- switch (BO->getOpcode()) {
- default: IsValid = false; break; // Do not perform transform!
- case Instruction::Add:
- IsValid = Shift.getOpcode() == Instruction::Shl;
- break;
- case Instruction::Or:
- case Instruction::Xor:
- HighBitSet = false;
- break;
- case Instruction::And:
- HighBitSet = true;
- break;
- }
-
- // If this is a signed shift right, and the high bit is modified
- // by the logical operation, do not perform the transformation.
- // The HighBitSet boolean indicates the value of the high bit of
- // the constant which would cause it to be modified for this
- // operation.
- //
- if (IsValid && Shift.getOpcode() == Instruction::AShr)
- IsValid = C.isNegative() == HighBitSet;
-
- return IsValid;
-}
-
Instruction *InstCombiner::FoldShiftByConstant(Value *Op0, Constant *Op1,
BinaryOperator &I) {
bool isLeftShift = I.getOpcode() == Instruction::Shl;
@@ -506,7 +472,33 @@ Instruction *InstCombiner::FoldShiftByCo
// shift is the only use, we can pull it out of the shift.
const APInt *Op0C;
if (match(Op0BO->getOperand(1), m_APInt(Op0C))) {
- if (canShiftBinOpWithConstantRHS(I, Op0BO, *Op0C)) {
+ bool isValid = true; // Valid only for And, Or, Xor
+ bool highBitSet = false; // Transform if high bit of constant set?
+
+ switch (Op0BO->getOpcode()) {
+ default: isValid = false; break; // Do not perform transform!
+ case Instruction::Add:
+ isValid = isLeftShift;
+ break;
+ case Instruction::Or:
+ case Instruction::Xor:
+ highBitSet = false;
+ break;
+ case Instruction::And:
+ highBitSet = true;
+ break;
+ }
+
+ // If this is a signed shift right, and the high bit is modified
+ // by the logical operation, do not perform the transformation.
+ // The highBitSet boolean indicates the value of the high bit of
+ // the constant which would cause it to be modified for this
+ // operation.
+ //
+ if (isValid && I.getOpcode() == Instruction::AShr)
+ isValid = Op0C->isNegative() == highBitSet;
+
+ if (isValid) {
Constant *NewRHS = ConstantExpr::get(I.getOpcode(),
cast<Constant>(Op0BO->getOperand(1)), Op1);
@@ -533,53 +525,6 @@ Instruction *InstCombiner::FoldShiftByCo
return BinaryOperator::CreateSub(NewRHS, NewShift);
}
}
-
- // If we have a select that conditionally executes some binary operator,
- // see if we can pull it the select and operator through the shift.
- //
- // For example, turning:
- // shl (select C, (add X, C1), X), C2
- // Into:
- // Y = shl X, C2
- // select C, (add Y, C1 << C2), Y
- Value *Cond;
- BinaryOperator *TBO;
- Value *FalseVal;
- if (match(Op0, m_Select(m_Value(Cond), m_OneUse(m_BinOp(TBO)),
- m_Value(FalseVal)))) {
- const APInt *C;
- if (!isa<Constant>(FalseVal) && TBO->getOperand(0) == FalseVal &&
- match(TBO->getOperand(1), m_APInt(C)) &&
- canShiftBinOpWithConstantRHS(I, TBO, *C)) {
- Constant *NewRHS = ConstantExpr::get(I.getOpcode(),
- cast<Constant>(TBO->getOperand(1)), Op1);
-
- Value *NewShift =
- Builder.CreateBinOp(I.getOpcode(), FalseVal, Op1);
- Value *NewOp = Builder.CreateBinOp(TBO->getOpcode(), NewShift,
- NewRHS);
- return SelectInst::Create(Cond, NewOp, NewShift);
- }
- }
-
- BinaryOperator *FBO;
- Value *TrueVal;
- if (match(Op0, m_Select(m_Value(Cond), m_Value(TrueVal),
- m_OneUse(m_BinOp(FBO))))) {
- const APInt *C;
- if (!isa<Constant>(TrueVal) && FBO->getOperand(0) == TrueVal &&
- match(FBO->getOperand(1), m_APInt(C)) &&
- canShiftBinOpWithConstantRHS(I, FBO, *C)) {
- Constant *NewRHS = ConstantExpr::get(I.getOpcode(),
- cast<Constant>(FBO->getOperand(1)), Op1);
-
- Value *NewShift =
- Builder.CreateBinOp(I.getOpcode(), TrueVal, Op1);
- Value *NewOp = Builder.CreateBinOp(FBO->getOpcode(), NewShift,
- NewRHS);
- return SelectInst::Create(Cond, NewShift, NewOp);
- }
- }
}
return nullptr;
Modified: llvm/trunk/test/Transforms/InstCombine/shift.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/shift.ll?rev=317518&r1=317517&r2=317518&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/shift.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/shift.ll Mon Nov 6 14:28:02 2017
@@ -1332,263 +1332,3 @@ define i7 @test65(i7 %a, i7 %b) {
%y = and i7 %x, 1 ; this extracts the lsb which should be 0 because we shifted an even number of bits and all even bits of the shift input are 0.
ret i7 %y
}
-
-define i32 @shl_select_add_true(i32 %x, i1 %cond) {
-; CHECK-LABEL: @shl_select_add_true(
-; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X:%.*]], 1
-; CHECK-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 14
-; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32 [[TMP2]], i32 [[TMP1]]
-; CHECK-NEXT: ret i32 [[TMP3]]
-;
- %1 = add i32 %x, 7
- %2 = select i1 %cond, i32 %1, i32 %x
- %3 = shl i32 %2, 1
- ret i32 %3
-}
-
-define i32 @shl_select_add_false(i32 %x, i1 %cond) {
-; CHECK-LABEL: @shl_select_add_false(
-; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X:%.*]], 1
-; CHECK-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 14
-; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32 [[TMP1]], i32 [[TMP2]]
-; CHECK-NEXT: ret i32 [[TMP3]]
-;
- %1 = add i32 %x, 7
- %2 = select i1 %cond, i32 %x, i32 %1
- %3 = shl i32 %2, 1
- ret i32 %3
-}
-
-define i32 @shl_select_and_true(i32 %x, i1 %cond) {
-; CHECK-LABEL: @shl_select_and_true(
-; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X:%.*]], 1
-; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 14
-; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32 [[TMP2]], i32 [[TMP1]]
-; CHECK-NEXT: ret i32 [[TMP3]]
-;
- %1 = and i32 %x, 7
- %2 = select i1 %cond, i32 %1, i32 %x
- %3 = shl i32 %2, 1
- ret i32 %3
-}
-
-define i32 @shl_select_and_false(i32 %x, i1 %cond) {
-; CHECK-LABEL: @shl_select_and_false(
-; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X:%.*]], 1
-; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 14
-; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32 [[TMP1]], i32 [[TMP2]]
-; CHECK-NEXT: ret i32 [[TMP3]]
-;
- %1 = and i32 %x, 7
- %2 = select i1 %cond, i32 %x, i32 %1
- %3 = shl i32 %2, 1
- ret i32 %3
-}
-
-define i32 @lshr_select_and_true(i32 %x, i1 %cond) {
-; CHECK-LABEL: @lshr_select_and_true(
-; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[X:%.*]], 1
-; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 3
-; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32 [[TMP2]], i32 [[TMP1]]
-; CHECK-NEXT: ret i32 [[TMP3]]
-;
- %1 = and i32 %x, 7
- %2 = select i1 %cond, i32 %1, i32 %x
- %3 = lshr i32 %2, 1
- ret i32 %3
-}
-
-define i32 @lshr_select_and_false(i32 %x, i1 %cond) {
-; CHECK-LABEL: @lshr_select_and_false(
-; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[X:%.*]], 1
-; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 3
-; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32 [[TMP1]], i32 [[TMP2]]
-; CHECK-NEXT: ret i32 [[TMP3]]
-;
- %1 = and i32 %x, 7
- %2 = select i1 %cond, i32 %x, i32 %1
- %3 = lshr i32 %2, 1
- ret i32 %3
-}
-
-define i32 @ashr_select_and_true(i32 %x, i1 %cond) {
-; CHECK-LABEL: @ashr_select_and_true(
-; CHECK-NEXT: [[TMP1:%.*]] = ashr i32 [[X:%.*]], 1
-; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], -1073741821
-; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32 [[TMP2]], i32 [[TMP1]]
-; CHECK-NEXT: ret i32 [[TMP3]]
-;
- %1 = and i32 %x, 2147483655
- %2 = select i1 %cond, i32 %1, i32 %x
- %3 = ashr i32 %2, 1
- ret i32 %3
-}
-
-define i32 @ashr_select_and_false(i32 %x, i1 %cond) {
-; CHECK-LABEL: @ashr_select_and_false(
-; CHECK-NEXT: [[TMP1:%.*]] = ashr i32 [[X:%.*]], 1
-; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], -1073741821
-; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32 [[TMP1]], i32 [[TMP2]]
-; CHECK-NEXT: ret i32 [[TMP3]]
-;
- %1 = and i32 %x, 2147483655
- %2 = select i1 %cond, i32 %x, i32 %1
- %3 = ashr i32 %2, 1
- ret i32 %3
-}
-
-define i32 @shl_select_or_true(i32 %x, i1 %cond) {
-; CHECK-LABEL: @shl_select_or_true(
-; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X:%.*]], 1
-; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], 14
-; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32 [[TMP2]], i32 [[TMP1]]
-; CHECK-NEXT: ret i32 [[TMP3]]
-;
- %1 = or i32 %x, 7
- %2 = select i1 %cond, i32 %1, i32 %x
- %3 = shl i32 %2, 1
- ret i32 %3
-}
-
-define i32 @shl_select_or_false(i32 %x, i1 %cond) {
-; CHECK-LABEL: @shl_select_or_false(
-; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X:%.*]], 1
-; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], 14
-; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32 [[TMP1]], i32 [[TMP2]]
-; CHECK-NEXT: ret i32 [[TMP3]]
-;
- %1 = or i32 %x, 7
- %2 = select i1 %cond, i32 %x, i32 %1
- %3 = shl i32 %2, 1
- ret i32 %3
-}
-
-define i32 @lshr_select_or_true(i32 %x, i1 %cond) {
-; CHECK-LABEL: @lshr_select_or_true(
-; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[X:%.*]], 1
-; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], 3
-; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32 [[TMP2]], i32 [[TMP1]]
-; CHECK-NEXT: ret i32 [[TMP3]]
-;
- %1 = or i32 %x, 7
- %2 = select i1 %cond, i32 %1, i32 %x
- %3 = lshr i32 %2, 1
- ret i32 %3
-}
-
-define i32 @lshr_select_or_false(i32 %x, i1 %cond) {
-; CHECK-LABEL: @lshr_select_or_false(
-; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[X:%.*]], 1
-; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], 3
-; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32 [[TMP1]], i32 [[TMP2]]
-; CHECK-NEXT: ret i32 [[TMP3]]
-;
- %1 = or i32 %x, 7
- %2 = select i1 %cond, i32 %x, i32 %1
- %3 = lshr i32 %2, 1
- ret i32 %3
-}
-
-define i32 @ashr_select_or_true(i32 %x, i1 %cond) {
-; CHECK-LABEL: @ashr_select_or_true(
-; CHECK-NEXT: [[TMP1:%.*]] = ashr i32 [[X:%.*]], 1
-; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], 3
-; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32 [[TMP2]], i32 [[TMP1]]
-; CHECK-NEXT: ret i32 [[TMP3]]
-;
- %1 = or i32 %x, 7
- %2 = select i1 %cond, i32 %1, i32 %x
- %3 = ashr i32 %2, 1
- ret i32 %3
-}
-
-define i32 @ashr_select_or_false(i32 %x, i1 %cond) {
-; CHECK-LABEL: @ashr_select_or_false(
-; CHECK-NEXT: [[TMP1:%.*]] = ashr i32 [[X:%.*]], 1
-; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], 3
-; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32 [[TMP1]], i32 [[TMP2]]
-; CHECK-NEXT: ret i32 [[TMP3]]
-;
- %1 = or i32 %x, 7
- %2 = select i1 %cond, i32 %x, i32 %1
- %3 = ashr i32 %2, 1
- ret i32 %3
-}
-
-define i32 @shl_select_xor_true(i32 %x, i1 %cond) {
-; CHECK-LABEL: @shl_select_xor_true(
-; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X:%.*]], 1
-; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[TMP1]], 14
-; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32 [[TMP2]], i32 [[TMP1]]
-; CHECK-NEXT: ret i32 [[TMP3]]
-;
- %1 = xor i32 %x, 7
- %2 = select i1 %cond, i32 %1, i32 %x
- %3 = shl i32 %2, 1
- ret i32 %3
-}
-
-define i32 @shl_select_xor_false(i32 %x, i1 %cond) {
-; CHECK-LABEL: @shl_select_xor_false(
-; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X:%.*]], 1
-; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[TMP1]], 14
-; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32 [[TMP1]], i32 [[TMP2]]
-; CHECK-NEXT: ret i32 [[TMP3]]
-;
- %1 = xor i32 %x, 7
- %2 = select i1 %cond, i32 %x, i32 %1
- %3 = shl i32 %2, 1
- ret i32 %3
-}
-
-define i32 @lshr_select_xor_true(i32 %x, i1 %cond) {
-; CHECK-LABEL: @lshr_select_xor_true(
-; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[X:%.*]], 1
-; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[TMP1]], 3
-; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32 [[TMP2]], i32 [[TMP1]]
-; CHECK-NEXT: ret i32 [[TMP3]]
-;
- %1 = xor i32 %x, 7
- %2 = select i1 %cond, i32 %1, i32 %x
- %3 = lshr i32 %2, 1
- ret i32 %3
-}
-
-define i32 @lshr_select_xor_false(i32 %x, i1 %cond) {
-; CHECK-LABEL: @lshr_select_xor_false(
-; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[X:%.*]], 1
-; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[TMP1]], 3
-; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32 [[TMP1]], i32 [[TMP2]]
-; CHECK-NEXT: ret i32 [[TMP3]]
-;
- %1 = xor i32 %x, 7
- %2 = select i1 %cond, i32 %x, i32 %1
- %3 = lshr i32 %2, 1
- ret i32 %3
-}
-
-define i32 @ashr_select_xor_true(i32 %x, i1 %cond) {
-; CHECK-LABEL: @ashr_select_xor_true(
-; CHECK-NEXT: [[TMP1:%.*]] = ashr i32 [[X:%.*]], 1
-; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[TMP1]], 3
-; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32 [[TMP2]], i32 [[TMP1]]
-; CHECK-NEXT: ret i32 [[TMP3]]
-;
- %1 = xor i32 %x, 7
- %2 = select i1 %cond, i32 %1, i32 %x
- %3 = ashr i32 %2, 1
- ret i32 %3
-}
-
-define i32 @ashr_select_xor_false(i32 %x, i1 %cond) {
-; CHECK-LABEL: @ashr_select_xor_false(
-; CHECK-NEXT: [[TMP1:%.*]] = ashr i32 [[X:%.*]], 1
-; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[TMP1]], 3
-; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32 [[TMP1]], i32 [[TMP2]]
-; CHECK-NEXT: ret i32 [[TMP3]]
-;
- %1 = xor i32 %x, 7
- %2 = select i1 %cond, i32 %x, i32 %1
- %3 = ashr i32 %2, 1
- ret i32 %3
-}
More information about the llvm-commits
mailing list