[llvm] r324249 - [X86] Teach X86DAGToDAGISel::shrinkAndImmediate to preserve upper 32 zeroes of a 64 bit mask.

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Mon Feb 5 08:54:07 PST 2018


Author: ctopper
Date: Mon Feb  5 08:54:07 2018
New Revision: 324249

URL: http://llvm.org/viewvc/llvm-project?rev=324249&view=rev
Log:
[X86] Teach X86DAGToDAGISel::shrinkAndImmediate to preserve upper 32 zeroes of a 64 bit mask.

If the upper 32 bits of a 64 bit mask are all zeros, we have special isel patterns to use a 32-bit and instead of a 64-bit and by relying on the impliciting zeroing of 32 bit ops.

This patch teachs shrinkAndImmediate not to break that optimization.

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

Modified:
    llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp
    llvm/trunk/test/CodeGen/X86/and-encoding.ll
    llvm/trunk/test/CodeGen/X86/shift-pair.ll

Modified: llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp?rev=324249&r1=324248&r2=324249&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Mon Feb  5 08:54:07 2018
@@ -2486,14 +2486,24 @@ bool X86DAGToDAGISel::shrinkAndImmediate
   if (!And1C)
     return false;
 
-  // Bail out if the mask constant is already negative. It can't shrink more.
+  // Bail out if the mask constant is already negative. It's can't shrink more.
+  // If the upper 32 bits of a 64 bit mask are all zeros, we have special isel
+  // patterns to use a 32-bit and instead of a 64-bit and by relying on the
+  // implicit zeroing of 32 bit ops. So we should check if the lower 32 bits
+  // are negative too.
   APInt MaskVal = And1C->getAPIntValue();
   unsigned MaskLZ = MaskVal.countLeadingZeros();
-  if (!MaskLZ)
+  if (!MaskLZ || (VT == MVT::i64 && MaskLZ == 32))
     return false;
 
+  // Don't extend into the upper 32 bits of a 64 bit mask.
+  if (VT == MVT::i64 && MaskLZ >= 32) {
+    MaskLZ -= 32;
+    MaskVal = MaskVal.trunc(32);
+  }
+
   SDValue And0 = And->getOperand(0);
-  APInt HighZeros = APInt::getHighBitsSet(VT.getSizeInBits(), MaskLZ);
+  APInt HighZeros = APInt::getHighBitsSet(MaskVal.getBitWidth(), MaskLZ);
   APInt NegMaskVal = MaskVal | HighZeros;
 
   // If a negative constant would not allow a smaller encoding, there's no need
@@ -2502,6 +2512,12 @@ bool X86DAGToDAGISel::shrinkAndImmediate
   if (MinWidth > 32 || (MinWidth > 8 && MaskVal.getMinSignedBits() <= 32))
     return false;
 
+  // Extend masks if we truncated above.
+  if (VT == MVT::i64 && MaskVal.getBitWidth() < 64) {
+    NegMaskVal = NegMaskVal.zext(64);
+    HighZeros = HighZeros.zext(64);
+  }
+
   // The variable operand must be all zeros in the top bits to allow using the
   // new, negative constant as the mask.
   if (!CurDAG->MaskedValueIsZero(And0, HighZeros))

Modified: llvm/trunk/test/CodeGen/X86/and-encoding.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/and-encoding.ll?rev=324249&r1=324248&r2=324249&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/and-encoding.ll (original)
+++ llvm/trunk/test/CodeGen/X86/and-encoding.ll Mon Feb  5 08:54:07 2018
@@ -61,7 +61,7 @@ define i64 @lopped64_32to8(i64 %x) {
 ; CHECK-LABEL: lopped64_32to8:
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    shrq $36, %rdi # encoding: [0x48,0xc1,0xef,0x24]
-; CHECK-NEXT:    andq $-16, %rdi # encoding: [0x48,0x83,0xe7,0xf0]
+; CHECK-NEXT:    andl $-16, %edi # encoding: [0x83,0xe7,0xf0]
 ; CHECK-NEXT:    movq %rdi, %rax # encoding: [0x48,0x89,0xf8]
 ; CHECK-NEXT:    retq # encoding: [0xc3]
   %shr = lshr i64 %x, 36

Modified: llvm/trunk/test/CodeGen/X86/shift-pair.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/shift-pair.ll?rev=324249&r1=324248&r2=324249&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/shift-pair.ll (original)
+++ llvm/trunk/test/CodeGen/X86/shift-pair.ll Mon Feb  5 08:54:07 2018
@@ -5,7 +5,7 @@ define i64 @test(i64 %A) {
 ; CHECK-LABEL: test:
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    shrq $54, %rdi
-; CHECK-NEXT:    andq $-4, %rdi
+; CHECK-NEXT:    andl $-4, %edi
 ; CHECK-NEXT:    movq %rdi, %rax
 ; CHECK-NEXT:    retq
     %B = lshr i64 %A, 56




More information about the llvm-commits mailing list