[llvm] 4c37372 - [X86] promoteExtBeforeAdd - determine if an addition is implicitly NSW/NUW

Simon Pilgrim via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 3 09:33:08 PDT 2023


Author: Simon Pilgrim
Date: 2023-10-03T17:32:28+01:00
New Revision: 4c37372daef153ace445286f83f6e4f836327162

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

LOG: [X86] promoteExtBeforeAdd - determine if an addition is implicitly NSW/NUW

Pulled out of D155472

Added: 
    

Modified: 
    llvm/lib/Target/X86/X86ISelLowering.cpp
    llvm/test/CodeGen/X86/addr-mode-matcher-3.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 0921f1a5c00fc7d..c4cd2a672fe7b26 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -52207,9 +52207,13 @@ static SDValue promoteExtBeforeAdd(SDNode *Ext, SelectionDAG &DAG,
   if (Add.getOpcode() != ISD::ADD)
     return SDValue();
 
+  SDValue AddOp0 = Add.getOperand(0);
+  SDValue AddOp1 = Add.getOperand(1);
   bool Sext = Ext->getOpcode() == ISD::SIGN_EXTEND;
   bool NSW = Add->getFlags().hasNoSignedWrap();
   bool NUW = Add->getFlags().hasNoUnsignedWrap();
+  NSW = NSW || (Sext && DAG.willNotOverflowAdd(true, AddOp0, AddOp1));
+  NUW = NUW || (!Sext && DAG.willNotOverflowAdd(false, AddOp0, AddOp1));
 
   // We need an 'add nsw' feeding into the 'sext' or 'add nuw' feeding
   // into the 'zext'
@@ -52219,8 +52223,8 @@ static SDValue promoteExtBeforeAdd(SDNode *Ext, SelectionDAG &DAG,
   // Having a constant operand to the 'add' ensures that we are not increasing
   // the instruction count because the constant is extended for free below.
   // A constant operand can also become the displacement field of an LEA.
-  auto *AddOp1 = dyn_cast<ConstantSDNode>(Add.getOperand(1));
-  if (!AddOp1)
+  auto *AddOp1C = dyn_cast<ConstantSDNode>(AddOp1);
+  if (!AddOp1C)
     return SDValue();
 
   // Don't make the 'add' bigger if there's no hope of combining it with some
@@ -52239,10 +52243,9 @@ static SDValue promoteExtBeforeAdd(SDNode *Ext, SelectionDAG &DAG,
     return SDValue();
 
   // Everything looks good, so pull the '{s|z}ext' ahead of the 'add'.
-  int64_t AddConstant = Sext ? AddOp1->getSExtValue() : AddOp1->getZExtValue();
-  SDValue AddOp0 = Add.getOperand(0);
+  int64_t AddC = Sext ? AddOp1C->getSExtValue() : AddOp1C->getZExtValue();
   SDValue NewExt = DAG.getNode(Ext->getOpcode(), SDLoc(Ext), VT, AddOp0);
-  SDValue NewConstant = DAG.getConstant(AddConstant, SDLoc(Add), VT);
+  SDValue NewConstant = DAG.getConstant(AddC, SDLoc(Add), VT);
 
   // The wider add is guaranteed to not wrap because both operands are
   // sign-extended.

diff  --git a/llvm/test/CodeGen/X86/addr-mode-matcher-3.ll b/llvm/test/CodeGen/X86/addr-mode-matcher-3.ll
index 9896b745187aadd..daa521d3917cdf7 100644
--- a/llvm/test/CodeGen/X86/addr-mode-matcher-3.ll
+++ b/llvm/test/CodeGen/X86/addr-mode-matcher-3.ll
@@ -13,9 +13,8 @@ define i32 @mask_add_sext_i32_i64(ptr %base, i32 %i) {
 ; X64-LABEL: mask_add_sext_i32_i64:
 ; X64:       # %bb.0:
 ; X64-NEXT:    sarl $24, %esi
-; X64-NEXT:    addl $3, %esi
 ; X64-NEXT:    movslq %esi, %rax
-; X64-NEXT:    movl (%rdi,%rax,4), %eax
+; X64-NEXT:    movl 12(%rdi,%rax,4), %eax
 ; X64-NEXT:    retq
   %mask = ashr i32 %i, 24
   %offset = add i32 %mask, 3
@@ -38,8 +37,7 @@ define i32 @mask_add_zext_i32_i64(ptr %base, i32 %i) {
 ; X64:       # %bb.0:
 ; X64-NEXT:    # kill: def $esi killed $esi def $rsi
 ; X64-NEXT:    andl $15, %esi
-; X64-NEXT:    addl $3, %esi
-; X64-NEXT:    movl (%rdi,%rsi,4), %eax
+; X64-NEXT:    movl 12(%rdi,%rsi,4), %eax
 ; X64-NEXT:    retq
   %mask = and i32 %i, 15
   %offset = add i32 %mask, 3


        


More information about the llvm-commits mailing list