diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 1add486255b897..099492ec230201 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -10054,8 +10054,7 @@ SDValue DAGCombiner::visitSHL(SDNode *N) { // TODO: Should we limit this with isLegalAddImmediate? if (N0.getOpcode() == ISD::SIGN_EXTEND && N0.getOperand(0).getOpcode() == ISD::ADD && - N0.getOperand(0)->getFlags().hasNoSignedWrap() && N0->hasOneUse() && - N0.getOperand(0)->hasOneUse() && + N0.getOperand(0)->getFlags().hasNoSignedWrap() && TLI.isDesirableToCommuteWithShift(N, Level)) { SDValue Add = N0.getOperand(0); SDLoc DL(N0); diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index 20e0210bcec5b6..58535cca4901d7 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -3370,6 +3370,17 @@ X86TargetLowering::preferredShiftLegalizationStrategy( ExpansionFactor); } +bool X86TargetLowering::isDesirableToCommuteWithShift( + const SDNode *N, CombineLevel Level) const { + assert((N->getOpcode() == ISD::SHL || N->getOpcode() == ISD::SRA || + N->getOpcode() == ISD::SRL) && + "Expected shift op"); + SDValue N0 = N->getOperand(0).getOpcode() == ISD::SIGN_EXTEND + ? N->getOperand(0)->getOperand(0) + : N->getOperand(0); + return N0.hasOneUse(); +} + bool X86TargetLowering::shouldSplatInsEltVarIndex(EVT VT) const { // Any legal vector type can be splatted more efficiently than // loading/spilling from memory. diff --git a/llvm/lib/Target/X86/X86ISelLowering.h b/llvm/lib/Target/X86/X86ISelLowering.h index 3b1b2603fd8fc6..546444355d1617 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.h +++ b/llvm/lib/Target/X86/X86ISelLowering.h @@ -1172,6 +1172,9 @@ namespace llvm { preferredShiftLegalizationStrategy(SelectionDAG &DAG, SDNode *N, unsigned ExpansionFactor) const override; + bool isDesirableToCommuteWithShift(const SDNode *N, + CombineLevel Level) const override; + bool shouldSplatInsEltVarIndex(EVT VT) const override; bool shouldConvertFpToSat(unsigned Op, EVT FPVT, EVT VT) const override { diff --git a/llvm/test/CodeGen/RISCV/riscv-shifted-extend.ll b/llvm/test/CodeGen/RISCV/riscv-shifted-extend.ll index 957f44f9f669de..f07a7af9197c5d 100644 --- a/llvm/test/CodeGen/RISCV/riscv-shifted-extend.ll +++ b/llvm/test/CodeGen/RISCV/riscv-shifted-extend.ll @@ -5,12 +5,10 @@ define void @test(ptr nocapture noundef writeonly %array1, i32 noundef signext %a, i32 noundef signext %b) { ; RV64-LABEL: test: ; RV64: # %bb.0: # %entry -; RV64-NEXT: addiw a3, a1, 5 -; RV64-NEXT: slli a4, a3, 2 -; RV64-NEXT: add a4, a0, a4 -; RV64-NEXT: sw a2, 0(a4) +; RV64-NEXT: addi a3, a1, 5 ; RV64-NEXT: slli a1, a1, 2 ; RV64-NEXT: add a0, a1, a0 +; RV64-NEXT: sw a2, 20(a0) ; RV64-NEXT: sw a2, 24(a0) ; RV64-NEXT: sw a3, 140(a0) ; RV64-NEXT: ret @@ -34,18 +32,16 @@ entry: define void @test1(ptr nocapture noundef %array1, i32 noundef signext %a, i32 noundef signext %b, i32 noundef signext %x) { ; RV64-LABEL: test1: ; RV64: # %bb.0: # %entry -; RV64-NEXT: addiw a4, a1, 5 -; RV64-NEXT: slli a5, a4, 2 -; RV64-NEXT: add a5, a0, a5 -; RV64-NEXT: mv a6, a4 +; RV64-NEXT: addi a4, a1, 5 +; RV64-NEXT: mv a5, a4 ; RV64-NEXT: bgtz a3, .LBB1_2 ; RV64-NEXT: # %bb.1: # %entry -; RV64-NEXT: mv a6, a2 +; RV64-NEXT: mv a5, a2 ; RV64-NEXT: .LBB1_2: # %entry -; RV64-NEXT: sw a6, 0(a5) ; RV64-NEXT: slli a1, a1, 2 ; RV64-NEXT: add a0, a1, a0 -; RV64-NEXT: sw a6, 24(a0) +; RV64-NEXT: sw a5, 20(a0) +; RV64-NEXT: sw a5, 24(a0) ; RV64-NEXT: sw a4, 140(a0) ; RV64-NEXT: ret entry: diff --git a/llvm/test/CodeGen/X86/pr65895.ll b/llvm/test/CodeGen/X86/pr65895.ll index 4fbbed4b18aff0..b9691e6bfd359d 100644 --- a/llvm/test/CodeGen/X86/pr65895.ll +++ b/llvm/test/CodeGen/X86/pr65895.ll @@ -21,10 +21,11 @@ define i32 @PR65895() { ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 ; CHECK-NEXT: jmp .LBB0_2 ; CHECK-NEXT: .LBB0_3: # %for.end +; CHECK-NEXT: movzbl %al, %ecx ; CHECK-NEXT: addb $-3, %al ; CHECK-NEXT: movsbl %al, %eax ; CHECK-NEXT: movl %eax, d(%rip) -; CHECK-NEXT: leal 247(%rax,%rax,2), %eax +; CHECK-NEXT: leal 241(%rax,%rcx,2), %eax ; CHECK-NEXT: movb $1, c(%rip) ; CHECK-NEXT: movsbq %al, %rax ; CHECK-NEXT: movq %rax, e(%rip)