]> granicus.if.org Git - llvm/commitdiff
[DAG] enhance computeKnownBits to handle SHL with vector splat constant
authorSanjay Patel <spatel@rotateright.com>
Fri, 21 Oct 2016 20:16:27 +0000 (20:16 +0000)
committerSanjay Patel <spatel@rotateright.com>
Fri, 21 Oct 2016 20:16:27 +0000 (20:16 +0000)
Also, use APInt to avoid crashing on types larger than vNi64.

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

lib/CodeGen/SelectionDAG/SelectionDAG.cpp
test/CodeGen/X86/combine-shl.ll
test/CodeGen/X86/negate.ll

index 56945b4bf984f4a115e1bcd4e977b91a5f931391..974322aabc162046d2d135b4cf63a28e7356ab18 100644 (file)
@@ -2144,23 +2144,21 @@ void SelectionDAG::computeKnownBits(SDValue Op, APInt &KnownZero,
       KnownZero |= APInt::getHighBitsSet(BitWidth, BitWidth - 1);
     break;
   case ISD::SHL:
-    // (shl X, C1) & C2 == 0   iff   (X & C2 >>u C1) == 0
-    if (ConstantSDNode *SA = dyn_cast<ConstantSDNode>(Op.getOperand(1))) {
-      unsigned ShAmt = SA->getZExtValue();
-
+    if (ConstantSDNode *SA = isConstOrConstSplat(Op.getOperand(1))) {
       // If the shift count is an invalid immediate, don't do anything.
-      if (ShAmt >= BitWidth)
+      APInt ShAmt = SA->getAPIntValue();
+      if (ShAmt.uge(BitWidth))
         break;
 
-      computeKnownBits(Op.getOperand(0), KnownZero, KnownOne, Depth+1);
-      KnownZero <<= ShAmt;
-      KnownOne  <<= ShAmt;
+      computeKnownBits(Op.getOperand(0), KnownZero, KnownOne, Depth + 1);
+      KnownZero = KnownZero << ShAmt;
+      KnownOne = KnownOne << ShAmt;
       // low bits known zero.
-      KnownZero |= APInt::getLowBitsSet(BitWidth, ShAmt);
+      KnownZero |= APInt::getLowBitsSet(BitWidth, ShAmt.getZExtValue());
     }
     break;
   case ISD::SRL:
-    // (ushr X, C1) & C2 == 0   iff  (-1 >> C1) & C2 == 0
+    // FIXME: Reuse isConstOrConstSplat + APInt from above.
     if (ConstantSDNode *SA = dyn_cast<ConstantSDNode>(Op.getOperand(1))) {
       unsigned ShAmt = SA->getZExtValue();
 
@@ -2177,6 +2175,7 @@ void SelectionDAG::computeKnownBits(SDValue Op, APInt &KnownZero,
     }
     break;
   case ISD::SRA:
+    // FIXME: Reuse isConstOrConstSplat + APInt from above.
     if (ConstantSDNode *SA = dyn_cast<ConstantSDNode>(Op.getOperand(1))) {
       unsigned ShAmt = SA->getZExtValue();
 
index 3f3871ec5c3317ecd30f97165f35141546e4ea34..64ed1cea8d4ab7a976b16e0a9c53f5afedb94f65 100644 (file)
@@ -61,16 +61,12 @@ define <4 x i32> @combine_vec_shl_by_zero(<4 x i32> %x) {
 define <4 x i32> @combine_vec_shl_known_zero0(<4 x i32> %x) {
 ; SSE-LABEL: combine_vec_shl_known_zero0:
 ; SSE:       # BB#0:
-; SSE-NEXT:    pxor %xmm1, %xmm1
-; SSE-NEXT:    pblendw {{.*#+}} xmm0 = xmm1[0],xmm0[1],xmm1[2],xmm0[3],xmm1[4],xmm0[5],xmm1[6],xmm0[7]
-; SSE-NEXT:    pslld $16, %xmm0
+; SSE-NEXT:    xorps %xmm0, %xmm0
 ; SSE-NEXT:    retq
 ;
 ; AVX-LABEL: combine_vec_shl_known_zero0:
 ; AVX:       # BB#0:
-; AVX-NEXT:    vpxor %xmm1, %xmm1, %xmm1
-; AVX-NEXT:    vpblendw {{.*#+}} xmm0 = xmm1[0],xmm0[1],xmm1[2],xmm0[3],xmm1[4],xmm0[5],xmm1[6],xmm0[7]
-; AVX-NEXT:    vpslld $16, %xmm0, %xmm0
+; AVX-NEXT:    vxorps %xmm0, %xmm0, %xmm0
 ; AVX-NEXT:    retq
   %1 = and <4 x i32> %x, <i32 4294901760, i32 4294901760, i32 4294901760, i32 4294901760>
   %2 = shl <4 x i32> %1, <i32 16, i32 16, i32 16, i32 16>
index e42794d184ecc2ce74db657675d29634eeb2e94d..6f07378e0e46b22ccb9ac6e451a9848f461681b6 100644 (file)
@@ -35,10 +35,7 @@ define i8 @negate_zero_or_minsigned_nsw(i8 %x) {
 define <4 x i32> @negate_zero_or_minsigned_nsw_vec(<4 x i32> %x) {
 ; CHECK-LABEL: negate_zero_or_minsigned_nsw_vec:
 ; CHECK:       # BB#0:
-; CHECK-NEXT:    pslld $31, %xmm0
-; CHECK-NEXT:    pxor %xmm1, %xmm1
-; CHECK-NEXT:    psubd %xmm0, %xmm1
-; CHECK-NEXT:    movdqa %xmm1, %xmm0
+; CHECK-NEXT:    xorps %xmm0, %xmm0
 ; CHECK-NEXT:    retq
 ;
   %signbit = shl <4 x i32> %x, <i32 31, i32 31, i32 31, i32 31>