]> granicus.if.org Git - llvm/commitdiff
[X86] When converting (x << C1) AND C2 to (x AND (C2>>C1)) << C1 during isel, try...
authorCraig Topper <craig.topper@intel.com>
Sat, 6 Apr 2019 19:00:11 +0000 (19:00 +0000)
committerCraig Topper <craig.topper@intel.com>
Sat, 6 Apr 2019 19:00:11 +0000 (19:00 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@357848 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/X86ISelDAGToDAG.cpp
test/CodeGen/X86/narrow-shl-cst.ll

index acd6e23a10cd4faec0d6ee888249d30fb5913eb3..fb48b087b415cd05f9468a6da2d9ee84f6c9921e 100644 (file)
@@ -3586,16 +3586,23 @@ void X86DAGToDAGISel::Select(SDNode *Node) {
     // Check the minimum bitwidth for the new constant.
     // TODO: Using 16 and 8 bit operations is also possible for or32 & xor32.
     auto CanShrinkImmediate = [&](int64_t &ShiftedVal) {
+      if (Opcode == ISD::AND) {
+        // AND32ri is the same as AND64ri32 with zext imm.
+        // Try this before sign extended immediates below.
+        ShiftedVal = (uint64_t)Val >> ShAmt;
+        if (NVT == MVT::i64 && !isUInt<32>(Val) && isUInt<32>(ShiftedVal))
+          return true;
+      }
       ShiftedVal = Val >> ShAmt;
       if ((!isInt<8>(Val) && isInt<8>(ShiftedVal)) ||
           (!isInt<32>(Val) && isInt<32>(ShiftedVal)))
         return true;
-      // For 64-bit we can also try unsigned 32 bit immediates.
-      // AND32ri is the same as AND64ri32 with zext imm.
-      // MOV32ri+OR64r is cheaper than MOV64ri64+OR64rr
-      ShiftedVal = (uint64_t)Val >> ShAmt;
-      if (NVT == MVT::i64 && !isUInt<32>(Val) && isUInt<32>(ShiftedVal))
-        return true;
+      if (Opcode != ISD::AND) {
+        // MOV32ri+OR64r/XOR64r is cheaper than MOV64ri64+OR64rr/XOR64rr
+        ShiftedVal = (uint64_t)Val >> ShAmt;
+        if (NVT == MVT::i64 && !isUInt<32>(Val) && isUInt<32>(ShiftedVal))
+          return true;
+      }
       return false;
     };
 
index 3389ff731c900ad4c873555d6a163da02fc883a6..0174803d449e87c0bd75ec6d4c782e531d1f6c55 100644 (file)
@@ -66,7 +66,7 @@ define i64 @test6(i64 %x) nounwind {
 ; CHECK-LABEL: test6:
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    movq %rdi, %rax
-; CHECK-NEXT:    andq $-65536, %rax # imm = 0xFFFF0000
+; CHECK-NEXT:    andl $-65536, %eax # imm = 0xFFFF0000
 ; CHECK-NEXT:    shlq $32, %rax
 ; CHECK-NEXT:    retq
   %and = shl i64 %x, 32