diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index 0921f1a5c00fc..c4cd2a672fe7b 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(Add.getOperand(1)); - if (!AddOp1) + auto *AddOp1C = dyn_cast(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 9896b745187aa..daa521d3917cd 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