[llvm] a8cef6b - [X86] promoteExtBeforeAdd - add support for or/xor 'addlike' patterns

Simon Pilgrim via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 11 02:17:55 PDT 2023


Author: Simon Pilgrim
Date: 2023-09-11T10:17:34+01:00
New Revision: a8cef6b58e2d41f04ed4fa63c3f628eac1a28925

URL: https://github.com/llvm/llvm-project/commit/a8cef6b58e2d41f04ed4fa63c3f628eac1a28925
DIFF: https://github.com/llvm/llvm-project/commit/a8cef6b58e2d41f04ed4fa63c3f628eac1a28925.diff

LOG: [X86] promoteExtBeforeAdd - add support for or/xor 'addlike' patterns

Fold zext(addlike(x, C)) --> add(zext(x), C_zext) if its likely to help us create LEA instructions

Addresses some regressions exposed by D155472

Added: 
    

Modified: 
    llvm/lib/Target/X86/X86ISelLowering.cpp
    llvm/test/CodeGen/X86/lea-2.ll
    llvm/test/CodeGen/X86/select_const.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 7a9ee45c6beed40..01d0b1749c1e3d0 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -52131,11 +52131,12 @@ static SDValue combineSignExtendInReg(SDNode *N, SelectionDAG &DAG,
   return SDValue();
 }
 
-/// sext(add_nsw(x, C)) --> add(sext(x), C_sext)
-/// zext(add_nuw(x, C)) --> add(zext(x), C_zext)
-/// Promoting a sign/zero extension ahead of a no overflow 'add' exposes
-/// opportunities to combine math ops, use an LEA, or use a complex addressing
-/// mode. This can eliminate extend, add, and shift instructions.
+/// sext(add_nsw(x, C)) --> add_nsw(sext(x), C_sext)
+/// zext(add_nuw(x, C)) --> add_nuw(zext(x), C_zext)
+/// zext(addlike(x, C)) --> add(zext(x), C_zext)
+/// Promoting a sign/zero extension ahead of a no overflow 'add' or 'addlike'
+/// exposes opportunities to combine math ops, use an LEA, or use a complex
+/// addressing mode. This can eliminate extend, add, and shift instructions.
 static SDValue promoteExtBeforeAdd(SDNode *Ext, SelectionDAG &DAG,
                                    const X86Subtarget &Subtarget) {
   if (Ext->getOpcode() != ISD::SIGN_EXTEND &&
@@ -52147,17 +52148,19 @@ static SDValue promoteExtBeforeAdd(SDNode *Ext, SelectionDAG &DAG,
   if (VT != MVT::i64)
     return SDValue();
 
-  SDValue Add = Ext->getOperand(0);
-  if (Add.getOpcode() != ISD::ADD)
-    return SDValue();
-
+  bool NSW = false, NUW = false;
   bool Sext = Ext->getOpcode() == ISD::SIGN_EXTEND;
-  bool NSW = Add->getFlags().hasNoSignedWrap();
-  bool NUW = Add->getFlags().hasNoUnsignedWrap();
 
-  // We need an 'add nsw' feeding into the 'sext' or 'add nuw' feeding
-  // into the 'zext'
-  if ((Sext && !NSW) || (!Sext && !NUW))
+  SDValue Add = Ext->getOperand(0);
+  unsigned AddOpc = Add->getOpcode();
+  if (AddOpc == ISD::ADD) {
+    NSW = Add->getFlags().hasNoSignedWrap();
+    NUW = Add->getFlags().hasNoUnsignedWrap();
+    // We need an 'add nsw' feeding into the 'sext' or 'add nuw' feeding
+    // into the 'zext'
+    if ((Sext && !NSW) || (!Sext && !NUW))
+      return SDValue();
+  } else if (!(!Sext && DAG.isADDLike(Add)))
     return SDValue();
 
   // Having a constant operand to the 'add' ensures that we are not increasing
@@ -52193,7 +52196,7 @@ static SDValue promoteExtBeforeAdd(SDNode *Ext, SelectionDAG &DAG,
   SDNodeFlags Flags;
   Flags.setNoSignedWrap(NSW);
   Flags.setNoUnsignedWrap(NUW);
-  return DAG.getNode(ISD::ADD, SDLoc(Add), VT, NewExt, NewConstant, Flags);
+  return DAG.getNode(AddOpc, SDLoc(Add), VT, NewExt, NewConstant, Flags);
 }
 
 // If we face {ANY,SIGN,ZERO}_EXTEND that is applied to a CMOV with constant

diff  --git a/llvm/test/CodeGen/X86/lea-2.ll b/llvm/test/CodeGen/X86/lea-2.ll
index 953972e499690f5..c91e2f297405baa 100644
--- a/llvm/test/CodeGen/X86/lea-2.ll
+++ b/llvm/test/CodeGen/X86/lea-2.ll
@@ -26,7 +26,7 @@ define i32 @test1(i32 %A, i32 %B) {
   ret i32 %t4
 }
 
-; TODO: The addlike OR instruction should fold into the LEA.
+; The addlike OR instruction should fold into the LEA.
 
 define i64 @test2(i32 %a0, i64 %a1) {
 ; X32-LABEL: test2:
@@ -44,8 +44,7 @@ define i64 @test2(i32 %a0, i64 %a1) {
 ; X64:       # %bb.0:
 ; X64-NEXT:    # kill: def $edi killed $edi def $rdi
 ; X64-NEXT:    andl $-8, %edi
-; X64-NEXT:    orl $2, %edi
-; X64-NEXT:    leaq (%rsi,%rdi,2), %rax
+; X64-NEXT:    leaq 4(%rsi,%rdi,2), %rax
 ; X64-NEXT:    retq
   %x1 = and i32 %a0, -8
   %x2 = or i32 %x1, 2

diff  --git a/llvm/test/CodeGen/X86/select_const.ll b/llvm/test/CodeGen/X86/select_const.ll
index dd054348ac01418..17cfaf53ff57c70 100644
--- a/llvm/test/CodeGen/X86/select_const.ll
+++ b/llvm/test/CodeGen/X86/select_const.ll
@@ -626,8 +626,8 @@ define i64 @select_pow2_
diff _neg_invert(i1 zeroext %cond) {
 ;
 ; X64-LABEL: select_pow2_
diff _neg_invert:
 ; X64:       # %bb.0:
-; X64-NEXT:    xorb $1, %dil
-; X64-NEXT:    movzbl %dil, %eax
+; X64-NEXT:    movl %edi, %eax
+; X64-NEXT:    xorq $1, %rax
 ; X64-NEXT:    shlq $7, %rax
 ; X64-NEXT:    addq $-99, %rax
 ; X64-NEXT:    retq


        


More information about the llvm-commits mailing list