[llvm] r313577 - [DAGCombiner] fold assertzexts separated by trunc

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 18 15:05:35 PDT 2017


Author: spatel
Date: Mon Sep 18 15:05:35 2017
New Revision: 313577

URL: http://llvm.org/viewvc/llvm-project?rev=313577&view=rev
Log:
[DAGCombiner] fold assertzexts separated by trunc

If we have an AssertZext of a truncated value that has already been AssertZext'ed, 
we can assert on the wider source op to improve the zext-y knowledge:
 assert (trunc (assert X, i8) to iN), i1 --> trunc (assert X, i1) to iN

This moves a fold from being Mips-specific to general combining, and x86 shows
improvements.

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


Modified:
    llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
    llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp
    llvm/trunk/test/CodeGen/X86/bool-zext.ll
    llvm/trunk/test/CodeGen/X86/critical-edge-split-2.ll
    llvm/trunk/test/CodeGen/X86/fp128-select.ll
    llvm/trunk/test/CodeGen/X86/illegal-bitfield-loadstore.ll
    llvm/trunk/test/CodeGen/X86/mask-negated-bool.ll
    llvm/trunk/test/CodeGen/X86/negate-i1.ll
    llvm/trunk/test/CodeGen/X86/select_const.ll
    llvm/trunk/test/CodeGen/X86/sext-i1.ll

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=313577&r1=313576&r2=313577&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Mon Sep 18 15:05:35 2017
@@ -7970,16 +7970,39 @@ SDValue DAGCombiner::visitANY_EXTEND(SDN
   return SDValue();
 }
 
+// TODO: These transforms should work with AssertSext too.
+// Change the function name, comments, opcode references, and caller.
 SDValue DAGCombiner::visitAssertZext(SDNode *N) {
   SDValue N0 = N->getOperand(0);
   SDValue N1 = N->getOperand(1);
-  EVT EVT = cast<VTSDNode>(N1)->getVT();
+  EVT AssertVT = cast<VTSDNode>(N1)->getVT();
 
   // fold (assertzext (assertzext x, vt), vt) -> (assertzext x, vt)
   if (N0.getOpcode() == ISD::AssertZext &&
-      EVT == cast<VTSDNode>(N0.getOperand(1))->getVT())
+      AssertVT == cast<VTSDNode>(N0.getOperand(1))->getVT())
     return N0;
 
+  if (N0.getOpcode() == ISD::TRUNCATE && N0.hasOneUse() &&
+      N0.getOperand(0).getOpcode() == ISD::AssertZext) {
+    // We have an assert, truncate, assert sandwich. Make one stronger assert
+    // by asserting on the smallest asserted type to the larger source type.
+    // This eliminates the later assert:
+    // assert (trunc (assert X, i8) to iN), i1 --> trunc (assert X, i1) to iN
+    // assert (trunc (assert X, i1) to iN), i8 --> trunc (assert X, i1) to iN
+    SDValue BigA = N0.getOperand(0);
+    EVT BigA_AssertVT = cast<VTSDNode>(BigA.getOperand(1))->getVT();
+    assert(BigA_AssertVT.bitsLE(N0.getValueType()) &&
+           "Asserting zero/sign-extended bits from a type larger than the "
+           "truncated destination does not provide information");
+
+    SDLoc DL(N);
+    EVT MinAssertVT = AssertVT.bitsLT(BigA_AssertVT) ? AssertVT : BigA_AssertVT;
+    SDValue MinAssertVTVal = DAG.getValueType(MinAssertVT);
+    SDValue NewAssert = DAG.getNode(ISD::AssertZext, DL, BigA.getValueType(),
+                                    BigA.getOperand(0), MinAssertVTVal);
+    return DAG.getNode(ISD::TRUNCATE, DL, N->getValueType(0), NewAssert);
+  }
+
   return SDValue();
 }
 

Modified: llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp?rev=313577&r1=313576&r2=313577&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp Mon Sep 18 15:05:35 2017
@@ -1112,37 +1112,6 @@ static SDValue performADDCombine(SDNode
   return DAG.getNode(ISD::ADD, DL, ValTy, Add1, Lo);
 }
 
-static SDValue performAssertZextCombine(SDNode *N, SelectionDAG &DAG,
-                                        TargetLowering::DAGCombinerInfo &DCI,
-                                        const MipsSubtarget &Subtarget) {
-  SDValue N0 = N->getOperand(0);
-  EVT NarrowerVT = cast<VTSDNode>(N->getOperand(1))->getVT();
-
-  if (N0.getOpcode() != ISD::TRUNCATE)
-    return SDValue();
-
-  if (N0.getOperand(0).getOpcode() != ISD::AssertZext)
-    return SDValue();
-
-  // fold (AssertZext (trunc (AssertZext x))) -> (trunc (AssertZext x))
-  // if the type of the extension of the innermost AssertZext node is
-  // smaller from that of the outermost node, eg:
-  // (AssertZext:i32 (trunc:i32 (AssertZext:i64 X, i32)), i8)
-  //   -> (trunc:i32 (AssertZext X, i8))
-  SDValue WiderAssertZext = N0.getOperand(0);
-  EVT WiderVT = cast<VTSDNode>(WiderAssertZext->getOperand(1))->getVT();
-
-  if (NarrowerVT.bitsLT(WiderVT)) {
-    SDValue NewAssertZext = DAG.getNode(
-        ISD::AssertZext, SDLoc(N), WiderAssertZext.getValueType(),
-        WiderAssertZext.getOperand(0), DAG.getValueType(NarrowerVT));
-    return DAG.getNode(ISD::TRUNCATE, SDLoc(N), N->getValueType(0),
-                       NewAssertZext);
-  }
-
-  return SDValue();
-}
-
 static SDValue performSHLCombine(SDNode *N, SelectionDAG &DAG,
                                  TargetLowering::DAGCombinerInfo &DCI,
                                  const MipsSubtarget &Subtarget) {
@@ -1215,8 +1184,6 @@ SDValue  MipsTargetLowering::PerformDAGC
     return performORCombine(N, DAG, DCI, Subtarget);
   case ISD::ADD:
     return performADDCombine(N, DAG, DCI, Subtarget);
-  case ISD::AssertZext:
-    return performAssertZextCombine(N, DAG, DCI, Subtarget);
   case ISD::SHL:
     return performSHLCombine(N, DAG, DCI, Subtarget);
   case ISD::SUB:

Modified: llvm/trunk/test/CodeGen/X86/bool-zext.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/bool-zext.ll?rev=313577&r1=313576&r2=313577&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/bool-zext.ll (original)
+++ llvm/trunk/test/CodeGen/X86/bool-zext.ll Mon Sep 18 15:05:35 2017
@@ -2,7 +2,7 @@
 ; RUN: llc < %s -mtriple=i686-unknown-unknown | FileCheck %s -check-prefix=X32
 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s -check-prefix=X64
 
-; Check that the argument gets zero-extended before calling.
+; It's not necessary to zero-extend the arg because it is specified 'zeroext'. 
 define void @bar1(i1 zeroext %v1) nounwind ssp {
 ; X32-LABEL: bar1:
 ; X32:       # BB#0:
@@ -14,7 +14,6 @@ define void @bar1(i1 zeroext %v1) nounwi
 ;
 ; X64-LABEL: bar1:
 ; X64:       # BB#0:
-; X64-NEXT:    movzbl %dil, %edi
 ; X64-NEXT:    xorl %eax, %eax
 ; X64-NEXT:    jmp foo1 # TAILCALL
   %conv = zext i1 %v1 to i32

Modified: llvm/trunk/test/CodeGen/X86/critical-edge-split-2.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/critical-edge-split-2.ll?rev=313577&r1=313576&r2=313577&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/critical-edge-split-2.ll (original)
+++ llvm/trunk/test/CodeGen/X86/critical-edge-split-2.ll Mon Sep 18 15:05:35 2017
@@ -12,7 +12,7 @@ define i16 @test1(i1 zeroext %C, i8** no
 ; CHECK-LABEL: test1:
 ; CHECK:       # BB#0: # %entry
 ; CHECK-NEXT:    movw $1, %ax
-; CHECK-NEXT:    testb %dil, %dil
+; CHECK-NEXT:    testl %edi, %edi
 ; CHECK-NEXT:    jne .LBB0_2
 ; CHECK-NEXT:  # BB#1: # %cond.false.i
 ; CHECK-NEXT:    movl $g_4, %eax

Modified: llvm/trunk/test/CodeGen/X86/fp128-select.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/fp128-select.ll?rev=313577&r1=313576&r2=313577&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/fp128-select.ll (original)
+++ llvm/trunk/test/CodeGen/X86/fp128-select.ll Mon Sep 18 15:05:35 2017
@@ -11,7 +11,7 @@
 define void @test_select(fp128* %p, fp128* %q, i1 zeroext %c) {
 ; MMX-LABEL: test_select:
 ; MMX:       # BB#0:
-; MMX-NEXT:    testb %dl, %dl
+; MMX-NEXT:    testl %edx, %edx
 ; MMX-NEXT:    jne .LBB0_1
 ; MMX-NEXT:  # BB#2:
 ; MMX-NEXT:    movaps {{.*}}(%rip), %xmm0
@@ -25,7 +25,7 @@ define void @test_select(fp128* %p, fp12
 ; CHECK-LABEL: test_select:
 ; CHECK:       # BB#0:
 ; CHECK-NEXT:    xorl %eax, %eax
-; CHECK-NEXT:    testb %dl, %dl
+; CHECK-NEXT:    testl %edx, %edx
 ; CHECK-NEXT:    cmovneq (%rdi), %rax
 ; CHECK-NEXT:    movabsq $9223231299366420480, %rcx # imm = 0x7FFF800000000000
 ; CHECK-NEXT:    cmovneq 8(%rdi), %rcx

Modified: llvm/trunk/test/CodeGen/X86/illegal-bitfield-loadstore.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/illegal-bitfield-loadstore.ll?rev=313577&r1=313576&r2=313577&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/illegal-bitfield-loadstore.ll (original)
+++ llvm/trunk/test/CodeGen/X86/illegal-bitfield-loadstore.ll Mon Sep 18 15:05:35 2017
@@ -87,16 +87,15 @@ define void @i24_insert_bit(i24* %a, i1
 ;
 ; X64-LABEL: i24_insert_bit:
 ; X64:       # BB#0:
-; X64-NEXT:    movzbl %sil, %eax
-; X64-NEXT:    movzwl (%rdi), %ecx
-; X64-NEXT:    movzbl 2(%rdi), %edx
-; X64-NEXT:    movb %dl, 2(%rdi)
-; X64-NEXT:    shll $16, %edx
-; X64-NEXT:    orl %ecx, %edx
-; X64-NEXT:    shll $13, %eax
-; X64-NEXT:    andl $16769023, %edx # imm = 0xFFDFFF
-; X64-NEXT:    orl %eax, %edx
-; X64-NEXT:    movw %dx, (%rdi)
+; X64-NEXT:    movzwl (%rdi), %eax
+; X64-NEXT:    movzbl 2(%rdi), %ecx
+; X64-NEXT:    movb %cl, 2(%rdi)
+; X64-NEXT:    shll $16, %ecx
+; X64-NEXT:    orl %eax, %ecx
+; X64-NEXT:    shll $13, %esi
+; X64-NEXT:    andl $16769023, %ecx # imm = 0xFFDFFF
+; X64-NEXT:    orl %esi, %ecx
+; X64-NEXT:    movw %cx, (%rdi)
 ; X64-NEXT:    retq
   %extbit = zext i1 %bit to i24
   %b = load i24, i24* %a, align 1
@@ -185,7 +184,7 @@ define void @i56_insert_bit(i56* %a, i1
 ;
 ; X64-LABEL: i56_insert_bit:
 ; X64:       # BB#0:
-; X64-NEXT:    movzbl %sil, %eax
+; X64-NEXT:    movl %esi, %eax
 ; X64-NEXT:    movzwl 4(%rdi), %ecx
 ; X64-NEXT:    movzbl 6(%rdi), %edx
 ; X64-NEXT:    movb %dl, 6(%rdi)

Modified: llvm/trunk/test/CodeGen/X86/mask-negated-bool.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/mask-negated-bool.ll?rev=313577&r1=313576&r2=313577&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/mask-negated-bool.ll (original)
+++ llvm/trunk/test/CodeGen/X86/mask-negated-bool.ll Mon Sep 18 15:05:35 2017
@@ -16,7 +16,7 @@ define i32 @mask_negated_zext_bool1(i1 %
 define i32 @mask_negated_zext_bool2(i1 zeroext %x) {
 ; CHECK-LABEL: mask_negated_zext_bool2:
 ; CHECK:       # BB#0:
-; CHECK-NEXT:    movzbl %dil, %eax
+; CHECK-NEXT:    movl %edi, %eax
 ; CHECK-NEXT:    retq
   %ext = zext i1 %x to i32
   %neg = sub i32 0, %ext
@@ -50,7 +50,7 @@ define i32 @mask_negated_sext_bool1(i1 %
 define i32 @mask_negated_sext_bool2(i1 zeroext %x) {
 ; CHECK-LABEL: mask_negated_sext_bool2:
 ; CHECK:       # BB#0:
-; CHECK-NEXT:    movzbl %dil, %eax
+; CHECK-NEXT:    movl %edi, %eax
 ; CHECK-NEXT:    retq
   %ext = sext i1 %x to i32
   %neg = sub i32 0, %ext

Modified: llvm/trunk/test/CodeGen/X86/negate-i1.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/negate-i1.ll?rev=313577&r1=313576&r2=313577&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/negate-i1.ll (original)
+++ llvm/trunk/test/CodeGen/X86/negate-i1.ll Mon Sep 18 15:05:35 2017
@@ -58,9 +58,8 @@ define i16 @select_i16_neg1_or_0(i1 %a)
 define i16 @select_i16_neg1_or_0_zeroext(i1 zeroext %a) {
 ; X64-LABEL: select_i16_neg1_or_0_zeroext:
 ; X64:       # BB#0:
-; X64-NEXT:    movzbl %dil, %eax
-; X64-NEXT:    negl %eax
-; X64-NEXT:    # kill: %AX<def> %AX<kill> %EAX<kill>
+; X64-NEXT:    negl %edi
+; X64-NEXT:    movl %edi, %eax
 ; X64-NEXT:    retq
 ;
 ; X32-LABEL: select_i16_neg1_or_0_zeroext:
@@ -94,8 +93,8 @@ define i32 @select_i32_neg1_or_0(i1 %a)
 define i32 @select_i32_neg1_or_0_zeroext(i1 zeroext %a) {
 ; X64-LABEL: select_i32_neg1_or_0_zeroext:
 ; X64:       # BB#0:
-; X64-NEXT:    movzbl %dil, %eax
-; X64-NEXT:    negl %eax
+; X64-NEXT:    negl %edi
+; X64-NEXT:    movl %edi, %eax
 ; X64-NEXT:    retq
 ;
 ; X32-LABEL: select_i32_neg1_or_0_zeroext:
@@ -130,7 +129,7 @@ define i64 @select_i64_neg1_or_0(i1 %a)
 define i64 @select_i64_neg1_or_0_zeroext(i1 zeroext %a) {
 ; X64-LABEL: select_i64_neg1_or_0_zeroext:
 ; X64:       # BB#0:
-; X64-NEXT:    movzbl %dil, %eax
+; X64-NEXT:    movl %edi, %eax
 ; X64-NEXT:    negq %rax
 ; X64-NEXT:    retq
 ;

Modified: llvm/trunk/test/CodeGen/X86/select_const.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/select_const.ll?rev=313577&r1=313576&r2=313577&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/select_const.ll (original)
+++ llvm/trunk/test/CodeGen/X86/select_const.ll Mon Sep 18 15:05:35 2017
@@ -53,7 +53,7 @@ define i32 @select_1_or_0(i1 %cond) {
 define i32 @select_1_or_0_zeroext(i1 zeroext %cond) {
 ; CHECK-LABEL: select_1_or_0_zeroext:
 ; CHECK:       # BB#0:
-; CHECK-NEXT:    movzbl %dil, %eax
+; CHECK-NEXT:    movl %edi, %eax
 ; CHECK-NEXT:    retq
   %sel = select i1 %cond, i32 1, i32 0
   ret i32 %sel
@@ -85,8 +85,8 @@ define i32 @select_0_or_neg1(i1 %cond) {
 define i32 @select_0_or_neg1_zeroext(i1 zeroext %cond) {
 ; CHECK-LABEL: select_0_or_neg1_zeroext:
 ; CHECK:       # BB#0:
-; CHECK-NEXT:    movzbl %dil, %eax
-; CHECK-NEXT:    decl %eax
+; CHECK-NEXT:    # kill: %EDI<def> %EDI<kill> %RDI<def>
+; CHECK-NEXT:    leal -1(%rdi), %eax
 ; CHECK-NEXT:    retq
   %sel = select i1 %cond, i32 0, i32 -1
   ret i32 %sel
@@ -119,8 +119,8 @@ define i32 @select_neg1_or_0(i1 %cond) {
 define i32 @select_neg1_or_0_zeroext(i1 zeroext %cond) {
 ; CHECK-LABEL: select_neg1_or_0_zeroext:
 ; CHECK:       # BB#0:
-; CHECK-NEXT:    movzbl %dil, %eax
-; CHECK-NEXT:    negl %eax
+; CHECK-NEXT:    negl %edi
+; CHECK-NEXT:    movl %edi, %eax
 ; CHECK-NEXT:    retq
   %sel = select i1 %cond, i32 -1, i32 0
   ret i32 %sel
@@ -151,8 +151,8 @@ define i32 @select_Cplus1_C(i1 %cond) {
 define i32 @select_Cplus1_C_zeroext(i1 zeroext %cond) {
 ; CHECK-LABEL: select_Cplus1_C_zeroext:
 ; CHECK:       # BB#0:
-; CHECK-NEXT:    movzbl %dil, %eax
-; CHECK-NEXT:    addl $41, %eax
+; CHECK-NEXT:    # kill: %EDI<def> %EDI<kill> %RDI<def>
+; CHECK-NEXT:    leal 41(%rdi), %eax
 ; CHECK-NEXT:    retq
   %sel = select i1 %cond, i32 42, i32 41
   ret i32 %sel
@@ -185,9 +185,8 @@ define i32 @select_C_Cplus1(i1 %cond) {
 define i32 @select_C_Cplus1_zeroext(i1 zeroext %cond) {
 ; CHECK-LABEL: select_C_Cplus1_zeroext:
 ; CHECK:       # BB#0:
-; CHECK-NEXT:    movzbl %dil, %ecx
 ; CHECK-NEXT:    movl $42, %eax
-; CHECK-NEXT:    subl %ecx, %eax
+; CHECK-NEXT:    subl %edi, %eax
 ; CHECK-NEXT:    retq
   %sel = select i1 %cond, i32 41, i32 42
   ret i32 %sel
@@ -413,7 +412,7 @@ define i32 @select_C1_C2(i1 %cond) {
 define i32 @select_C1_C2_zeroext(i1 zeroext %cond) {
 ; CHECK-LABEL: select_C1_C2_zeroext:
 ; CHECK:       # BB#0:
-; CHECK-NEXT:    testb %dil, %dil
+; CHECK-NEXT:    testl %edi, %edi
 ; CHECK-NEXT:    movl $421, %ecx # imm = 0x1A5
 ; CHECK-NEXT:    movl $42, %eax
 ; CHECK-NEXT:    cmovnel %ecx, %eax

Modified: llvm/trunk/test/CodeGen/X86/sext-i1.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/sext-i1.ll?rev=313577&r1=313576&r2=313577&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/sext-i1.ll (original)
+++ llvm/trunk/test/CodeGen/X86/sext-i1.ll Mon Sep 18 15:05:35 2017
@@ -144,8 +144,8 @@ define i32 @select_0_or_1s_zeroext(i1 ze
 ;
 ; X64-LABEL: select_0_or_1s_zeroext:
 ; X64:       # BB#0:
-; X64-NEXT:    movzbl %dil, %eax
-; X64-NEXT:    decl %eax
+; X64-NEXT:    # kill: %EDI<def> %EDI<kill> %RDI<def>
+; X64-NEXT:    leal -1(%rdi), %eax
 ; X64-NEXT:    retq
   %not = xor i1 %cond, 1
   %sext = sext i1 %not to i32




More information about the llvm-commits mailing list