Replace sra with srl if a single sign bit is required
authorRichard Sandiford <rsandifo@linux.vnet.ibm.com>
Thu, 17 Oct 2013 11:16:57 +0000 (11:16 +0000)
committerRichard Sandiford <rsandifo@linux.vnet.ibm.com>
Thu, 17 Oct 2013 11:16:57 +0000 (11:16 +0000)
E.g. (and (sra (i32 x) 31) 2) -> (and (srl (i32 x) 30) 2).

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@192884 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/SelectionDAG/TargetLowering.cpp
test/CodeGen/PowerPC/rlwimi-and.ll
test/CodeGen/SystemZ/shift-10.ll

index 9d6a3b40b915875edfe22e5f23ca6fce5e945169..4d30e7b50c7ac5cf79acda1c2fad7bd2edd8044c 100644 (file)
@@ -750,13 +750,24 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
 
       // If the input sign bit is known to be zero, or if none of the top bits
       // are demanded, turn this into an unsigned shift right.
-      if (KnownZero.intersects(SignBit) || (HighBits & ~NewMask) == HighBits) {
+      if (KnownZero.intersects(SignBit) || (HighBits & ~NewMask) == HighBits)
         return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::SRL, dl, VT,
                                                  Op.getOperand(0),
                                                  Op.getOperand(1)));
-      } else if (KnownOne.intersects(SignBit)) { // New bits are known one.
-        KnownOne |= HighBits;
+
+      int Log2 = NewMask.exactLogBase2();
+      if (Log2 >= 0) {
+        // The bit must come from the sign.
+        SDValue NewSA =
+          TLO.DAG.getConstant(BitWidth - 1 - Log2,
+                              Op.getOperand(1).getValueType());
+        return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::SRL, dl, VT,
+                                                 Op.getOperand(0), NewSA));
       }
+
+      if (KnownOne.intersects(SignBit))
+        // New bits are known one.
+        KnownOne |= HighBits;
     }
     break;
   case ISD::SIGN_EXTEND_INREG: {
index e20a13fec0f752b9b5cd35693cf87f7d491ced08..7963249ddf83ffe2e1aea52ce33c46822cd6eb35 100644 (file)
@@ -28,12 +28,11 @@ codeRepl17:                                       ; preds = %codeRepl4
   store i16 %rvml38.sroa.0.0.insert.insert, i16* undef, align 2
   unreachable
 
+; FIXME: the SLWI could be folded into the RLWIMI to give a rotate of 8.
 ; CHECK: @test
-; CHECK-DAG: slwi [[R1:[0-9]+]],
-; CHECK-DAG: rlwinm [[R2:[0-9]+]],
-; CHECK-DAG: srawi [[R3:[0-9]+]], [[R1]]
-; CHECK-DAG: rlwinm [[R4:[0-9]+]], [[R3]], 0, 23, 23
-; CHECK: rlwimi [[R4]], [[R2]], 0,
+; CHECK-DAG: slwi [[R1:[0-9]+]], {{[0-9]+}}, 31
+; CHECK-DAG: rlwinm [[R2:[0-9]+]], {{[0-9]+}}, 0, 31, 31
+; CHECK: rlwimi [[R2]], [[R1]], 9, 23, 23
 
 codeRepl29:                                       ; preds = %codeRepl1
   unreachable
index 3fd965745ed2f3b9eae53cbdfc7f3fda629cf3ed..46ed2180dfd4e4d72290d5efc06a33ede70b34b2 100644 (file)
@@ -64,3 +64,15 @@ define i64 @f5(i32 %a) {
   %or = or i64 %shl, 7
   ret i64 %or
 }
+
+; Test that SRA gets replaced with SRL if the sign bit is the only one
+; that matters.
+define i64 @f6(i64 %a) {
+; CHECK-LABEL: f6:
+; CHECK: risbg %r2, %r2, 55, 183, 19
+; CHECK: br %r14
+  %shl = shl i64 %a, 10
+  %shr = ashr i64 %shl, 60
+  %and = and i64 %shr, 256
+  ret i64 %and
+}