Skip to content

Commit 4c37372

Browse files
committed
[X86] promoteExtBeforeAdd - determine if an addition is implicitly NSW/NUW
Pulled out of D155472
1 parent d97f49b commit 4c37372

File tree

2 files changed

+10
-9
lines changed

2 files changed

+10
-9
lines changed

llvm/lib/Target/X86/X86ISelLowering.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52207,9 +52207,13 @@ static SDValue promoteExtBeforeAdd(SDNode *Ext, SelectionDAG &DAG,
5220752207
if (Add.getOpcode() != ISD::ADD)
5220852208
return SDValue();
5220952209

52210+
SDValue AddOp0 = Add.getOperand(0);
52211+
SDValue AddOp1 = Add.getOperand(1);
5221052212
bool Sext = Ext->getOpcode() == ISD::SIGN_EXTEND;
5221152213
bool NSW = Add->getFlags().hasNoSignedWrap();
5221252214
bool NUW = Add->getFlags().hasNoUnsignedWrap();
52215+
NSW = NSW || (Sext && DAG.willNotOverflowAdd(true, AddOp0, AddOp1));
52216+
NUW = NUW || (!Sext && DAG.willNotOverflowAdd(false, AddOp0, AddOp1));
5221352217

5221452218
// We need an 'add nsw' feeding into the 'sext' or 'add nuw' feeding
5221552219
// into the 'zext'
@@ -52219,8 +52223,8 @@ static SDValue promoteExtBeforeAdd(SDNode *Ext, SelectionDAG &DAG,
5221952223
// Having a constant operand to the 'add' ensures that we are not increasing
5222052224
// the instruction count because the constant is extended for free below.
5222152225
// A constant operand can also become the displacement field of an LEA.
52222-
auto *AddOp1 = dyn_cast<ConstantSDNode>(Add.getOperand(1));
52223-
if (!AddOp1)
52226+
auto *AddOp1C = dyn_cast<ConstantSDNode>(AddOp1);
52227+
if (!AddOp1C)
5222452228
return SDValue();
5222552229

5222652230
// 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,
5223952243
return SDValue();
5224052244

5224152245
// Everything looks good, so pull the '{s|z}ext' ahead of the 'add'.
52242-
int64_t AddConstant = Sext ? AddOp1->getSExtValue() : AddOp1->getZExtValue();
52243-
SDValue AddOp0 = Add.getOperand(0);
52246+
int64_t AddC = Sext ? AddOp1C->getSExtValue() : AddOp1C->getZExtValue();
5224452247
SDValue NewExt = DAG.getNode(Ext->getOpcode(), SDLoc(Ext), VT, AddOp0);
52245-
SDValue NewConstant = DAG.getConstant(AddConstant, SDLoc(Add), VT);
52248+
SDValue NewConstant = DAG.getConstant(AddC, SDLoc(Add), VT);
5224652249

5224752250
// The wider add is guaranteed to not wrap because both operands are
5224852251
// sign-extended.

llvm/test/CodeGen/X86/addr-mode-matcher-3.ll

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,8 @@ define i32 @mask_add_sext_i32_i64(ptr %base, i32 %i) {
1313
; X64-LABEL: mask_add_sext_i32_i64:
1414
; X64: # %bb.0:
1515
; X64-NEXT: sarl $24, %esi
16-
; X64-NEXT: addl $3, %esi
1716
; X64-NEXT: movslq %esi, %rax
18-
; X64-NEXT: movl (%rdi,%rax,4), %eax
17+
; X64-NEXT: movl 12(%rdi,%rax,4), %eax
1918
; X64-NEXT: retq
2019
%mask = ashr i32 %i, 24
2120
%offset = add i32 %mask, 3
@@ -38,8 +37,7 @@ define i32 @mask_add_zext_i32_i64(ptr %base, i32 %i) {
3837
; X64: # %bb.0:
3938
; X64-NEXT: # kill: def $esi killed $esi def $rsi
4039
; X64-NEXT: andl $15, %esi
41-
; X64-NEXT: addl $3, %esi
42-
; X64-NEXT: movl (%rdi,%rsi,4), %eax
40+
; X64-NEXT: movl 12(%rdi,%rsi,4), %eax
4341
; X64-NEXT: retq
4442
%mask = and i32 %i, 15
4543
%offset = add i32 %mask, 3

0 commit comments

Comments
 (0)