[llvm] r361043 - [InstCombine] canShiftBinOpWithConstantRHS(): drop bogus signbit check

Roman Lebedev via llvm-commits llvm-commits at lists.llvm.org
Fri May 17 08:52:49 PDT 2019


Author: lebedevri
Date: Fri May 17 08:52:49 2019
New Revision: 361043

URL: http://llvm.org/viewvc/llvm-project?rev=361043&view=rev
Log:
[InstCombine] canShiftBinOpWithConstantRHS(): drop bogus signbit check

Summary:
In D61918 i was looking at dropping it in DAGCombiner `visitShiftByConstant()`,
but as @craig.topper pointed out, it was copied from here.

That check claims that the transform is illegal otherwise.
That isn't true:
1. For `ISD::ADD`, we only process `ISD::SHL` outer shift => sign bit does not matter
   https://rise4fun.com/Alive/K4A
2. For `ISD::AND`, there is no restriction on constants:
   https://rise4fun.com/Alive/Wy3
3. For `ISD::OR`, there is no restriction on constants:
   https://rise4fun.com/Alive/GOH
3. For `ISD::XOR`, there is no restriction on constants:
   https://rise4fun.com/Alive/ml6

So, why is it there then?
As far as i can tell, it dates all the way back to original check-in rL7793.
I think we should just drop it.

Reviewers: spatel, craig.topper, efriedma, majnemer

Reviewed By: spatel

Subscribers: llvm-commits, craig.topper

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D61938

Modified:
    llvm/trunk/lib/Transforms/InstCombine/InstCombineShifts.cpp
    llvm/trunk/test/Transforms/InstCombine/pull-binop-through-shift.ll
    llvm/trunk/test/Transforms/InstCombine/pull-conditional-binop-through-shift.ll
    llvm/trunk/test/Transforms/InstCombine/trunc.ll

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineShifts.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineShifts.cpp?rev=361043&r1=361042&r2=361043&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineShifts.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineShifts.cpp Fri May 17 08:52:49 2019
@@ -312,35 +312,17 @@ 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?
-
+                                         BinaryOperator *BO) {
   switch (BO->getOpcode()) {
-  default: IsValid = false; break;   // Do not perform transform!
+  default:
+    return false; // Do not perform transform!
   case Instruction::Add:
-    IsValid = Shift.getOpcode() == Instruction::Shl;
-    break;
+    return Shift.getOpcode() == Instruction::Shl;
   case Instruction::Or:
   case Instruction::Xor:
-    HighBitSet = false;
-    break;
   case Instruction::And:
-    HighBitSet = true;
-    break;
+    return true;
   }
-
-  // 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,
@@ -507,7 +489,7 @@ 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)) {
+        if (canShiftBinOpWithConstantRHS(I, Op0BO)) {
           Constant *NewRHS = ConstantExpr::get(I.getOpcode(),
                                      cast<Constant>(Op0BO->getOperand(1)), Op1);
 
@@ -551,7 +533,7 @@ Instruction *InstCombiner::FoldShiftByCo
       const APInt *C;
       if (!isa<Constant>(FalseVal) && TBO->getOperand(0) == FalseVal &&
           match(TBO->getOperand(1), m_APInt(C)) &&
-          canShiftBinOpWithConstantRHS(I, TBO, *C)) {
+          canShiftBinOpWithConstantRHS(I, TBO)) {
         Constant *NewRHS = ConstantExpr::get(I.getOpcode(),
                                        cast<Constant>(TBO->getOperand(1)), Op1);
 
@@ -570,7 +552,7 @@ Instruction *InstCombiner::FoldShiftByCo
       const APInt *C;
       if (!isa<Constant>(TrueVal) && FBO->getOperand(0) == TrueVal &&
           match(FBO->getOperand(1), m_APInt(C)) &&
-          canShiftBinOpWithConstantRHS(I, FBO, *C)) {
+          canShiftBinOpWithConstantRHS(I, FBO)) {
         Constant *NewRHS = ConstantExpr::get(I.getOpcode(),
                                        cast<Constant>(FBO->getOperand(1)), Op1);
 

Modified: llvm/trunk/test/Transforms/InstCombine/pull-binop-through-shift.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/pull-binop-through-shift.ll?rev=361043&r1=361042&r2=361043&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/pull-binop-through-shift.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/pull-binop-through-shift.ll Fri May 17 08:52:49 2019
@@ -198,8 +198,8 @@ define i32 @and_nosignbit_ashr(i32 %x) {
 
 define i32 @or_signbit_ashr(i32 %x) {
 ; CHECK-LABEL: @or_signbit_ashr(
-; CHECK-NEXT:    [[T0:%.*]] = or i32 [[X:%.*]], -65536
-; CHECK-NEXT:    [[R:%.*]] = ashr i32 [[T0]], 8
+; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[X:%.*]], 8
+; CHECK-NEXT:    [[R:%.*]] = or i32 [[TMP1]], -256
 ; CHECK-NEXT:    ret i32 [[R]]
 ;
   %t0 = or i32 %x, 4294901760 ; 0xFFFF0000
@@ -219,8 +219,8 @@ define i32 @or_nosignbit_ashr(i32 %x) {
 
 define i32 @xor_signbit_ashr(i32 %x) {
 ; CHECK-LABEL: @xor_signbit_ashr(
-; CHECK-NEXT:    [[T0:%.*]] = xor i32 [[X:%.*]], -65536
-; CHECK-NEXT:    [[R:%.*]] = ashr i32 [[T0]], 8
+; CHECK-NEXT:    [[T0:%.*]] = ashr i32 [[X:%.*]], 8
+; CHECK-NEXT:    [[R:%.*]] = xor i32 [[T0]], -256
 ; CHECK-NEXT:    ret i32 [[R]]
 ;
   %t0 = xor i32 %x, 4294901760 ; 0xFFFF0000

Modified: llvm/trunk/test/Transforms/InstCombine/pull-conditional-binop-through-shift.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/pull-conditional-binop-through-shift.ll?rev=361043&r1=361042&r2=361043&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/pull-conditional-binop-through-shift.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/pull-conditional-binop-through-shift.ll Fri May 17 08:52:49 2019
@@ -221,9 +221,9 @@ define i32 @and_signbit_select_ashr(i32
 }
 define i32 @and_nosignbit_select_ashr(i32 %x, i1 %cond) {
 ; CHECK-LABEL: @and_nosignbit_select_ashr(
-; CHECK-NEXT:    [[T0:%.*]] = and i32 [[X:%.*]], 2147418112
-; CHECK-NEXT:    [[T1:%.*]] = select i1 [[COND:%.*]], i32 [[T0]], i32 [[X]]
-; CHECK-NEXT:    [[R:%.*]] = ashr i32 [[T1]], 8
+; CHECK-NEXT:    [[TMP1:%.*]] = ashr i32 [[X:%.*]], 8
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], 8388352
+; CHECK-NEXT:    [[R:%.*]] = select i1 [[COND:%.*]], i32 [[TMP2]], i32 [[TMP1]]
 ; CHECK-NEXT:    ret i32 [[R]]
 ;
   %t0 = and i32 %x, 2147418112 ; 0x7FFF0000
@@ -234,9 +234,9 @@ define i32 @and_nosignbit_select_ashr(i3
 
 define i32 @or_signbit_select_ashr(i32 %x, i1 %cond) {
 ; CHECK-LABEL: @or_signbit_select_ashr(
-; CHECK-NEXT:    [[T0:%.*]] = or i32 [[X:%.*]], -65536
-; CHECK-NEXT:    [[T1:%.*]] = select i1 [[COND:%.*]], i32 [[T0]], i32 [[X]]
-; CHECK-NEXT:    [[R:%.*]] = ashr i32 [[T1]], 8
+; CHECK-NEXT:    [[TMP1:%.*]] = ashr i32 [[X:%.*]], 8
+; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], -256
+; CHECK-NEXT:    [[R:%.*]] = select i1 [[COND:%.*]], i32 [[TMP2]], i32 [[TMP1]]
 ; CHECK-NEXT:    ret i32 [[R]]
 ;
   %t0 = or i32 %x, 4294901760 ; 0xFFFF0000
@@ -259,9 +259,9 @@ define i32 @or_nosignbit_select_ashr(i32
 
 define i32 @xor_signbit_select_ashr(i32 %x, i1 %cond) {
 ; CHECK-LABEL: @xor_signbit_select_ashr(
-; CHECK-NEXT:    [[T0:%.*]] = xor i32 [[X:%.*]], -65536
-; CHECK-NEXT:    [[T1:%.*]] = select i1 [[COND:%.*]], i32 [[T0]], i32 [[X]]
-; CHECK-NEXT:    [[R:%.*]] = ashr i32 [[T1]], 8
+; CHECK-NEXT:    [[TMP1:%.*]] = ashr i32 [[X:%.*]], 8
+; CHECK-NEXT:    [[TMP2:%.*]] = xor i32 [[TMP1]], -256
+; CHECK-NEXT:    [[R:%.*]] = select i1 [[COND:%.*]], i32 [[TMP2]], i32 [[TMP1]]
 ; CHECK-NEXT:    ret i32 [[R]]
 ;
   %t0 = xor i32 %x, 4294901760 ; 0xFFFF0000

Modified: llvm/trunk/test/Transforms/InstCombine/trunc.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/trunc.ll?rev=361043&r1=361042&r2=361043&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/trunc.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/trunc.ll Fri May 17 08:52:49 2019
@@ -125,8 +125,8 @@ define i16 @ashr_mul(i8 %X, i8 %Y) {
 
 define i32 @trunc_ashr(i32 %X) {
 ; CHECK-LABEL: @trunc_ashr(
-; CHECK-NEXT:    [[B:%.*]] = or i32 [[X:%.*]], -2147483648
-; CHECK-NEXT:    [[C:%.*]] = ashr i32 [[B]], 8
+; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[X:%.*]], 8
+; CHECK-NEXT:    [[C:%.*]] = or i32 [[TMP1]], -8388608
 ; CHECK-NEXT:    ret i32 [[C]]
 ;
   %A = zext i32 %X to i36
@@ -138,8 +138,8 @@ define i32 @trunc_ashr(i32 %X) {
 
 define <2 x i32> @trunc_ashr_vec(<2 x i32> %X) {
 ; CHECK-LABEL: @trunc_ashr_vec(
-; CHECK-NEXT:    [[B:%.*]] = or <2 x i32> [[X:%.*]], <i32 -2147483648, i32 -2147483648>
-; CHECK-NEXT:    [[C:%.*]] = ashr <2 x i32> [[B]], <i32 8, i32 8>
+; CHECK-NEXT:    [[TMP1:%.*]] = lshr <2 x i32> [[X:%.*]], <i32 8, i32 8>
+; CHECK-NEXT:    [[C:%.*]] = or <2 x i32> [[TMP1]], <i32 -8388608, i32 -8388608>
 ; CHECK-NEXT:    ret <2 x i32> [[C]]
 ;
   %A = zext <2 x i32> %X to <2 x i36>




More information about the llvm-commits mailing list