diff --git a/llvm/lib/Target/RISCV/RISCVLoadStoreOptimizer.cpp b/llvm/lib/Target/RISCV/RISCVLoadStoreOptimizer.cpp index a5e12c0a51112..0c98dbbe4cadf 100644 --- a/llvm/lib/Target/RISCV/RISCVLoadStoreOptimizer.cpp +++ b/llvm/lib/Target/RISCV/RISCVLoadStoreOptimizer.cpp @@ -482,10 +482,13 @@ RISCVLoadStoreOpt::mergePairedInsns(MachineBasicBlock::iterator I, bool MergeForward) { MachineBasicBlock::iterator E = I->getParent()->end(); MachineBasicBlock::iterator NextI = next_nodbg(I, E); - // If NextI is the second of the two instructions to be merged, we need - // to skip one further. Either way we merge will invalidate the iterator, - // and we don't need to scan the new instruction, as it's a pairwise - // instruction, which we're not considering for further action anyway. + // If NextI is the second of the two instructions to be merged, skip one + // further for now. For the MIPS load/store, the merge will invalidate the + // iterator, and we don't need to scan the new instruction, as it's a pairwise + // instruction, which we're not considering for further action anyway. For the + // Xqcilsm load/store, we may not want to do this as the second instruction + // could possibly be the first in another pair if we do not merge here. This + // is handled is the else block after the call to tryConvertToLdStPair below. if (NextI == Paired) NextI = next_nodbg(NextI, E); @@ -535,9 +538,16 @@ RISCVLoadStoreOpt::mergePairedInsns(MachineBasicBlock::iterator I, First = InsertionPoint; } + MachineFunction *MF = I->getMF(); + const RISCVSubtarget &STI = MF->getSubtarget(); + if (tryConvertToLdStPair(First, Second)) { LLVM_DEBUG(dbgs() << "Pairing load/store:\n "); LLVM_DEBUG(prev_nodbg(NextI, MBB.begin())->print(dbgs())); + } else if (!STI.is64Bit() && STI.hasVendorXqcilsm()) { + // We were unable to form the pair, so use the next non-debug instruction + // after the first instruction we had wanted to merge. + NextI = next_nodbg(I, E); } return NextI; diff --git a/llvm/test/CodeGen/RISCV/xqcilsm-lwmi-swmi.mir b/llvm/test/CodeGen/RISCV/xqcilsm-lwmi-swmi.mir index 1bb6599bb0e0f..971a62dbc0323 100644 --- a/llvm/test/CodeGen/RISCV/xqcilsm-lwmi-swmi.mir +++ b/llvm/test/CodeGen/RISCV/xqcilsm-lwmi-swmi.mir @@ -19,6 +19,9 @@ define void @no_pair_if_rd_is_x0_swmi() nounwind { ret void } define void @pair_if_rd_is_x0_setwmi() nounwind { ret void } define void @no_pair_if_lw_rd_equals_base() nounwind { ret void } + define void @second_pair_if_no_first_pair_lwmi() nounwind { ret void } + define void @second_pair_if_no_first_pair_swmi() nounwind { ret void } + define void @second_pair_if_no_first_pair_setwmi() nounwind { ret void } define void @pair_if_not_adjacent() nounwind { ret void } define void @pair_if_not_adjacent_use() nounwind { ret void } define void @no_pair_if_not_adjacent_use() nounwind { ret void } @@ -292,6 +295,60 @@ body: | $x11 = LW $x10, 24 :: (load (s32), align 4) PseudoRET +... +--- +name: second_pair_if_no_first_pair_lwmi +tracksRegLiveness: false +body: | + bb.0: + liveins: $x10 + ; CHECK-LABEL: name: second_pair_if_no_first_pair_lwmi + ; CHECK: liveins: $x10 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: $x0 = LW $x10, 0 :: (load (s32)) + ; CHECK-NEXT: $x1 = QC_LWMI $x10, 2, 4, implicit-def $x2 :: (load (s32)) + ; CHECK-NEXT: PseudoRET + $x0 = LW $x10, 0 :: (load (s32), align 4) + $x1 = LW $x10, 4 :: (load (s32), align 4) + $x2 = LW $x10, 8 :: (load (s32), align 4) + PseudoRET + +... +--- +name: second_pair_if_no_first_pair_swmi +tracksRegLiveness: false +body: | + bb.0: + liveins: $x10 + ; CHECK-LABEL: name: second_pair_if_no_first_pair_swmi + ; CHECK: liveins: $x10 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: SW $x0, $x10, 0 :: (store (s32)) + ; CHECK-NEXT: QC_SWMI $x1, $x10, 2, 4, implicit $x2 :: (store (s32)) + ; CHECK-NEXT: PseudoRET + SW $x0, $x10, 0 :: (store (s32), align 4) + SW $x1, $x10, 4 :: (store (s32), align 4) + SW $x2, $x10, 8 :: (store (s32), align 4) + PseudoRET + +... +--- +name: second_pair_if_no_first_pair_setwmi +tracksRegLiveness: false +body: | + bb.0: + liveins: $x10 + ; CHECK-LABEL: name: second_pair_if_no_first_pair_setwmi + ; CHECK: liveins: $x10 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: SW $x0, $x10, 0 :: (store (s32)) + ; CHECK-NEXT: QC_SETWMI $x2, $x10, 2, 4 :: (store (s32)) + ; CHECK-NEXT: PseudoRET + SW $x0, $x10, 0 :: (store (s32), align 4) + SW $x2, $x10, 4 :: (store (s32), align 4) + SW $x2, $x10, 8 :: (store (s32), align 4) + PseudoRET + ... --- # FIXME: Kill flags are not propagated correctly for the base register