diff --git a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp index c3b403743185a..94e60defc0c67 100644 --- a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp +++ b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp @@ -307,6 +307,25 @@ RISCVInstructionSelector::selectAddrRegImm(MachineOperand &Root) const { }}; } + if (isBaseWithConstantOffset(Root, MRI)) { + MachineOperand &LHS = RootDef->getOperand(1); + MachineOperand &RHS = RootDef->getOperand(2); + MachineInstr *LHSDef = MRI.getVRegDef(LHS.getReg()); + MachineInstr *RHSDef = MRI.getVRegDef(RHS.getReg()); + + int64_t RHSC = RHSDef->getOperand(1).getCImm()->getSExtValue(); + if (isInt<12>(RHSC)) { + if (LHSDef->getOpcode() == TargetOpcode::G_FRAME_INDEX) + return {{ + [=](MachineInstrBuilder &MIB) { MIB.add(LHSDef->getOperand(1)); }, + [=](MachineInstrBuilder &MIB) { MIB.addImm(RHSC); }, + }}; + + return {{[=](MachineInstrBuilder &MIB) { MIB.add(LHS); }, + [=](MachineInstrBuilder &MIB) { MIB.addImm(RHSC); }}}; + } + } + // TODO: Need to get the immediate from a G_PTR_ADD. Should this be done in // the combiner? return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(Root.getReg()); }, diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/load-rv32.mir b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/load-rv32.mir index 3855656a55dd9..d49afb20974c3 100644 --- a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/load-rv32.mir +++ b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/load-rv32.mir @@ -15,6 +15,11 @@ %ptr0 = alloca i32 ret void } + define void @load_fi_gep_i32() { + %ptr0 = alloca [2 x i32] + ret void + } + define void @load_gep_i32(ptr %addr) { ret void } ... --- name: load_i8 @@ -213,3 +218,50 @@ body: | PseudoRET implicit $x10 ... +--- +name: load_fi_gep_i32 +legalized: true +regBankSelected: true +tracksRegLiveness: true + +stack: + - { id: 0, name: ptr0, offset: 0, size: 8, alignment: 4 } + +body: | + bb.0: + ; CHECK-LABEL: name: load_fi_gep_i32 + ; CHECK: [[LW:%[0-9]+]]:gpr = LW %stack.0.ptr0, 4 :: (load (s32)) + ; CHECK-NEXT: $x10 = COPY [[LW]] + ; CHECK-NEXT: PseudoRET implicit $x10 + %0:gprb(p0) = G_FRAME_INDEX %stack.0.ptr0 + %1:gprb(s32) = G_CONSTANT i32 4 + %2:gprb(p0) = G_PTR_ADD %0(p0), %1(s32) + %3:gprb(s32) = G_LOAD %2(p0) :: (load (s32)) + $x10 = COPY %3(s32) + PseudoRET implicit $x10 + +... +--- +name: load_gep_i32 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $x10 + + ; CHECK-LABEL: name: load_gep_i32 + ; CHECK: liveins: $x10 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; CHECK-NEXT: [[LW:%[0-9]+]]:gpr = LW [[COPY]], 4 :: (load (s32)) + ; CHECK-NEXT: $x10 = COPY [[LW]] + ; CHECK-NEXT: PseudoRET implicit $x10 + %0:gprb(p0) = COPY $x10 + %1:gprb(s32) = G_CONSTANT i32 4 + %2:gprb(p0) = G_PTR_ADD %0(p0), %1(s32) + %3:gprb(s32) = G_LOAD %2(p0) :: (load (s32)) + $x10 = COPY %3(s32) + PseudoRET implicit $x10 + +... diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/load-rv64.mir b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/load-rv64.mir index 287c22e931a7e..8b4d940c7d500 100644 --- a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/load-rv64.mir +++ b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/load-rv64.mir @@ -25,6 +25,11 @@ %ptr0 = alloca i64 ret void } + define void @load_fi_gep_i64_i64() { + %ptr0 = alloca [2 x i64] + ret void + } + define void @load_gep_i64_i64(ptr %addr) { ret void } ... --- name: load_i8_i64 @@ -478,3 +483,50 @@ body: | PseudoRET implicit $x10 ... +--- +name: load_fi_gep_i64_i64 +legalized: true +regBankSelected: true +tracksRegLiveness: true + +stack: + - { id: 0, name: ptr0, offset: 0, size: 16, alignment: 8 } + +body: | + bb.0: + ; CHECK-LABEL: name: load_fi_gep_i64_i64 + ; CHECK: [[LD:%[0-9]+]]:gpr = LD %stack.0.ptr0, 8 :: (load (s64)) + ; CHECK-NEXT: $x10 = COPY [[LD]] + ; CHECK-NEXT: PseudoRET implicit $x10 + %0:gprb(p0) = G_FRAME_INDEX %stack.0.ptr0 + %1:gprb(s64) = G_CONSTANT i64 8 + %2:gprb(p0) = G_PTR_ADD %0(p0), %1(s64) + %3:gprb(s64) = G_LOAD %2(p0) :: (load (s64)) + $x10 = COPY %3(s64) + PseudoRET implicit $x10 + +... +--- +name: load_gep_i64_i64 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $x10 + + ; CHECK-LABEL: name: load_gep_i64_i64 + ; CHECK: liveins: $x10 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; CHECK-NEXT: [[LD:%[0-9]+]]:gpr = LD [[COPY]], 8 :: (load (s64)) + ; CHECK-NEXT: $x10 = COPY [[LD]] + ; CHECK-NEXT: PseudoRET implicit $x10 + %0:gprb(p0) = COPY $x10 + %1:gprb(s64) = G_CONSTANT i64 8 + %2:gprb(p0) = G_PTR_ADD %0(p0), %1(s64) + %3:gprb(s64) = G_LOAD %2(p0) :: (load (s64)) + $x10 = COPY %3(s64) + PseudoRET implicit $x10 + +... diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/store-rv32.mir b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/store-rv32.mir index 52d21fedc7caa..d320fb755da97 100644 --- a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/store-rv32.mir +++ b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/store-rv32.mir @@ -11,6 +11,11 @@ %ptr0 = alloca i32 ret void } + define void @store_fi_gep_i32(ptr %val) { + %ptr0 = alloca [2 x i32] + ret void + } + define void @store_gep_i32(i32 %val, ptr %addr) { ret void } ... --- name: store_i8 @@ -125,3 +130,54 @@ body: | PseudoRET ... +--- +name: store_fi_gep_i32 +legalized: true +regBankSelected: true +tracksRegLiveness: true + +stack: + - { id: 0, name: ptr0, offset: 0, size: 8, alignment: 4 } + +body: | + bb.0: + liveins: $x10 + + ; CHECK-LABEL: name: store_fi_gep_i32 + ; CHECK: liveins: $x10 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; CHECK-NEXT: SW [[COPY]], %stack.0.ptr0, 4 :: (store (s32)) + ; CHECK-NEXT: PseudoRET + %0:gprb(s32) = COPY $x10 + %1:gprb(p0) = G_FRAME_INDEX %stack.0.ptr0 + %2:gprb(s32) = G_CONSTANT i32 4 + %3:gprb(p0) = G_PTR_ADD %1(p0), %2(s32) + G_STORE %0(s32), %3(p0) :: (store (s32)) + PseudoRET + +... +--- +name: store_gep_i32 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $x10, $x11 + + ; CHECK-LABEL: name: store_gep_i32 + ; CHECK: liveins: $x10, $x11 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; CHECK-NEXT: SW [[COPY]], [[COPY1]], 4 :: (store (s32)) + ; CHECK-NEXT: PseudoRET + %0:gprb(s32) = COPY $x10 + %1:gprb(p0) = COPY $x11 + %2:gprb(s32) = G_CONSTANT i32 4 + %3:gprb(p0) = G_PTR_ADD %1(p0), %2(s32) + G_STORE %0(s32), %3(p0) :: (store (s32)) + PseudoRET + +... diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/store-rv64.mir b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/store-rv64.mir index b575c640e79b1..e6cd770648c2a 100644 --- a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/store-rv64.mir +++ b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/store-rv64.mir @@ -15,6 +15,11 @@ %ptr0 = alloca i64 ret void } + define void @store_fi_gep_i64_i64(ptr %val) { + %ptr0 = alloca [2 x i64] + ret void + } + define void @store_gep_i64_i64(i32 %val, ptr %addr) { ret void } ... --- name: store_i8_i64 @@ -247,3 +252,54 @@ body: | PseudoRET ... +--- +name: store_fi_gep_i64_i64 +legalized: true +regBankSelected: true +tracksRegLiveness: true + +stack: + - { id: 0, name: ptr0, offset: 0, size: 16, alignment: 8 } + +body: | + bb.0: + liveins: $x10 + + ; CHECK-LABEL: name: store_fi_gep_i64_i64 + ; CHECK: liveins: $x10 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; CHECK-NEXT: SD [[COPY]], %stack.0.ptr0, 8 :: (store (s64)) + ; CHECK-NEXT: PseudoRET + %0:gprb(s64) = COPY $x10 + %1:gprb(p0) = G_FRAME_INDEX %stack.0.ptr0 + %2:gprb(s64) = G_CONSTANT i64 8 + %3:gprb(p0) = G_PTR_ADD %1(p0), %2(s64) + G_STORE %0(s64), %3(p0) :: (store (s64)) + PseudoRET + +... +--- +name: store_gep_i64_i64 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $x10, $x11 + + ; CHECK-LABEL: name: store_gep_i64_i64 + ; CHECK: liveins: $x10, $x11 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; CHECK-NEXT: SD [[COPY]], [[COPY1]], 8 :: (store (s64)) + ; CHECK-NEXT: PseudoRET + %0:gprb(s64) = COPY $x10 + %1:gprb(p0) = COPY $x11 + %2:gprb(s64) = G_CONSTANT i64 8 + %3:gprb(p0) = G_PTR_ADD %1(p0), %2(s64) + G_STORE %0(s64), %3(p0) :: (store (s64)) + PseudoRET + +...