]> granicus.if.org Git - llvm/commitdiff
[X86] Don't select (cmp (and, imm), 0) to testw
authorCraig Topper <craig.topper@intel.com>
Thu, 28 Sep 2017 23:35:36 +0000 (23:35 +0000)
committerCraig Topper <craig.topper@intel.com>
Thu, 28 Sep 2017 23:35:36 +0000 (23:35 +0000)
Summary:
X86ISelDAGToDAG tries to analyze ANDs compared with 0 to optimize to narrower immediates using subregisters.

I don't think we should be optimizing to 16-bit test instructions. It goes against our normal behavior of promoting i16 operations to i32. It only saves one byte due to the need to add a 0x66 prefix. I think it would also be subject to a length changing prefix penalty in the decoders on Intel CPUs.

Reviewers: RKSimon, zvi, spatel

Reviewed By: spatel

Subscribers: llvm-commits

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

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

lib/Target/X86/X86ISelDAGToDAG.cpp
test/CodeGen/X86/tbm_patterns.ll
test/CodeGen/X86/test-shrink-bug.ll
test/CodeGen/X86/test-shrink.ll

index 84b1f9624ad9f1301e54ff160c6d41211ec3a2e4..eb0107a5fa4b442d9efcf61e306c3902b7d548c9 100644 (file)
@@ -3025,7 +3025,10 @@ void X86DAGToDAGISel::Select(SDNode *Node) {
       }
 
       // For example, "testl %eax, $32776" to "testw %ax, $32776".
-      if (isUInt<16>(Mask) && N0.getValueType() != MVT::i16 &&
+      // NOTE: We only want to form TESTW instructions if optimizing for
+      // min size. Otherwise we only save one byte and possibly get a length
+      // changing prefix penalty in the decoders.
+      if (OptForMinSize && isUInt<16>(Mask) && N0.getValueType() != MVT::i16 &&
           (!(Mask & 0x8000) || hasNoSignedComparisonUses(Node))) {
         SDValue Imm = CurDAG->getTargetConstant(Mask, dl, MVT::i16);
         SDValue Reg = N0.getOperand(0);
index a72b54056158f832f21b71a23b305a61d30e1450..e459e173eda9b4605f7b3d24dd6fbd11944daa2f 100644 (file)
@@ -53,7 +53,7 @@ define i32 @test_x86_tbm_bextri_u32_z2(i32 %a, i32 %b, i32 %c) nounwind {
 ; CHECK-LABEL: test_x86_tbm_bextri_u32_z2:
 ; CHECK:       # BB#0:
 ; CHECK-NEXT:    shrl $4, %edi
-; CHECK-NEXT:    testw $4095, %di # imm = 0xFFF
+; CHECK-NEXT:    testl $4095, %edi # imm = 0xFFF
 ; CHECK-NEXT:    cmovnel %edx, %esi
 ; CHECK-NEXT:    movl %esi, %eax
 ; CHECK-NEXT:    retq
@@ -114,7 +114,7 @@ define i64 @test_x86_tbm_bextri_u64_z2(i64 %a, i64 %b, i64 %c) nounwind {
 ; CHECK-LABEL: test_x86_tbm_bextri_u64_z2:
 ; CHECK:       # BB#0:
 ; CHECK-NEXT:    shrl $4, %edi
-; CHECK-NEXT:    testw $4095, %di # imm = 0xFFF
+; CHECK-NEXT:    testl $4095, %edi # imm = 0xFFF
 ; CHECK-NEXT:    cmovneq %rdx, %rsi
 ; CHECK-NEXT:    movq %rsi, %rax
 ; CHECK-NEXT:    retq
index 1bb1e63848321612740422aea97de6ff4b2af4ea..814e07f718b03f7f2ff543f1b37abd1cbb532207 100644 (file)
@@ -3,7 +3,7 @@
 ; Codegen shouldn't reduce the comparison down to testb $-1, %al
 ; because that changes the result of the signed test.
 ; PR5132
-; CHECK: testw  $255, %ax
+; CHECK: testl  $255, %eax
 
 target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
 target triple = "i386-apple-darwin10.0"
index 72f2d1fb86fdd78d2068f39beae40f26520f773f..e09ec43210e8649f59229120a8ec98cd5108ff40 100644 (file)
@@ -105,16 +105,33 @@ no:
   ret void
 }
 ; CHECK-64-LABEL: g64x16:
-; CHECK-64:   testw $-32640, %[[A0W:di|cx]]
+; CHECK-64:   testl $32896, %[[A0D:edi|ecx]]
 ; CHECK-64:   ret
 ; CHECK-32-LABEL: g64x16:
-; CHECK-32:   testw $-32640, %ax
+; CHECK-32:   testl $32896, %eax
 ; CHECK-32:   ret
 define void @g64x16(i64 inreg %x) nounwind {
   %t = and i64 %x, 32896
   %s = icmp eq i64 %t, 0
   br i1 %s, label %yes, label %no
 
+yes:
+  call void @bar()
+  ret void
+no:
+  ret void
+}
+; CHECK-64-LABEL: g64x16minsize:
+; CHECK-64:   testw $-32640, %[[A0W:di|cx]]
+; CHECK-64:   ret
+; CHECK-32-LABEL: g64x16minsize:
+; CHECK-32:   testw $-32640, %ax
+; CHECK-32:   ret
+define void @g64x16minsize(i64 inreg %x) nounwind minsize {
+  %t = and i64 %x, 32896
+  %s = icmp eq i64 %t, 0
+  br i1 %s, label %yes, label %no
+
 yes:
   call void @bar()
   ret void
@@ -122,16 +139,33 @@ no:
   ret void
 }
 ; CHECK-64-LABEL: g32x16:
-; CHECK-64:   testw $-32640, %[[A0W]]
+; CHECK-64:   testl $32896, %[[A0D]]
 ; CHECK-64:   ret
 ; CHECK-32-LABEL: g32x16:
-; CHECK-32:   testw $-32640, %ax
+; CHECK-32:   testl $32896, %eax
 ; CHECK-32:   ret
 define void @g32x16(i32 inreg %x) nounwind {
   %t = and i32 %x, 32896
   %s = icmp eq i32 %t, 0
   br i1 %s, label %yes, label %no
 
+yes:
+  call void @bar()
+  ret void
+no:
+  ret void
+}
+; CHECK-64-LABEL: g32x16minsize:
+; CHECK-64:   testw $-32640, %[[A0W]]
+; CHECK-64:   ret
+; CHECK-32-LABEL: g32x16minsize:
+; CHECK-32:   testw $-32640, %ax
+; CHECK-32:   ret
+define void @g32x16minsize(i32 inreg %x) nounwind minsize {
+  %t = and i32 %x, 32896
+  %s = icmp eq i32 %t, 0
+  br i1 %s, label %yes, label %no
+
 yes:
   call void @bar()
   ret void
@@ -139,7 +173,7 @@ no:
   ret void
 }
 ; CHECK-64-LABEL: g64x32:
-; CHECK-64:   testl $268468352, %e[[A0W]]
+; CHECK-64:   testl $268468352, %[[A0D]]
 ; CHECK-64:   ret
 ; CHECK-32-LABEL: g64x32:
 ; CHECK-32:   testl $268468352, %eax