@@ -2723,29 +2723,29 @@ bool AArch64InstructionSelector::select(MachineInstr &I) {
2723
2723
case TargetOpcode::G_ZEXTLOAD:
2724
2724
case TargetOpcode::G_LOAD:
2725
2725
case TargetOpcode::G_STORE: {
2726
+ GLoadStore &LdSt = cast<GLoadStore>(I);
2726
2727
bool IsZExtLoad = I.getOpcode () == TargetOpcode::G_ZEXTLOAD;
2727
- LLT PtrTy = MRI.getType (I. getOperand ( 1 ). getReg ());
2728
+ LLT PtrTy = MRI.getType (LdSt. getPointerReg ());
2728
2729
2729
2730
if (PtrTy != LLT::pointer (0 , 64 )) {
2730
2731
LLVM_DEBUG (dbgs () << " Load/Store pointer has type: " << PtrTy
2731
2732
<< " , expected: " << LLT::pointer (0 , 64 ) << ' \n ' );
2732
2733
return false ;
2733
2734
}
2734
2735
2735
- auto &MemOp = **I.memoperands_begin ();
2736
- uint64_t MemSizeInBytes = MemOp.getSize ();
2737
- unsigned MemSizeInBits = MemSizeInBytes * 8 ;
2738
- AtomicOrdering Order = MemOp.getSuccessOrdering ();
2736
+ uint64_t MemSizeInBytes = LdSt.getMemSize ();
2737
+ unsigned MemSizeInBits = LdSt.getMemSizeInBits ();
2738
+ AtomicOrdering Order = LdSt.getMMO ().getSuccessOrdering ();
2739
2739
2740
2740
// Need special instructions for atomics that affect ordering.
2741
2741
if (Order != AtomicOrdering::NotAtomic &&
2742
2742
Order != AtomicOrdering::Unordered &&
2743
2743
Order != AtomicOrdering::Monotonic) {
2744
- assert (I. getOpcode () != TargetOpcode::G_ZEXTLOAD );
2744
+ assert (!isa<GZExtLoad>(LdSt) );
2745
2745
if (MemSizeInBytes > 64 )
2746
2746
return false ;
2747
2747
2748
- if (I. getOpcode () == TargetOpcode::G_LOAD ) {
2748
+ if (isa<GLoad>(LdSt) ) {
2749
2749
static unsigned Opcodes[] = {AArch64::LDARB, AArch64::LDARH,
2750
2750
AArch64::LDARW, AArch64::LDARX};
2751
2751
I.setDesc (TII.get (Opcodes[Log2_32 (MemSizeInBytes)]));
@@ -2759,7 +2759,7 @@ bool AArch64InstructionSelector::select(MachineInstr &I) {
2759
2759
}
2760
2760
2761
2761
#ifndef NDEBUG
2762
- const Register PtrReg = I. getOperand ( 1 ). getReg ();
2762
+ const Register PtrReg = LdSt. getPointerReg ();
2763
2763
const RegisterBank &PtrRB = *RBI.getRegBank (PtrReg, MRI, TRI);
2764
2764
// Sanity-check the pointer register.
2765
2765
assert (PtrRB.getID () == AArch64::GPRRegBankID &&
@@ -2768,13 +2768,31 @@ bool AArch64InstructionSelector::select(MachineInstr &I) {
2768
2768
" Load/Store pointer operand isn't a pointer" );
2769
2769
#endif
2770
2770
2771
- const Register ValReg = I.getOperand (0 ).getReg ();
2771
+ const Register ValReg = LdSt.getReg (0 );
2772
+ const LLT ValTy = MRI.getType (ValReg);
2772
2773
const RegisterBank &RB = *RBI.getRegBank (ValReg, MRI, TRI);
2773
2774
2775
+ // The code below doesn't support truncating stores, so we need to split it
2776
+ // again.
2777
+ if (isa<GStore>(LdSt) && ValTy.getSizeInBits () > MemSizeInBits) {
2778
+ unsigned SubReg;
2779
+ LLT MemTy = LdSt.getMMO ().getMemoryType ();
2780
+ auto *RC = getRegClassForTypeOnBank (MemTy, RB, RBI);
2781
+ if (!getSubRegForClass (RC, TRI, SubReg))
2782
+ return false ;
2783
+
2784
+ // Generate a subreg copy.
2785
+ auto Copy = MIB.buildInstr (TargetOpcode::COPY, {MemTy}, {})
2786
+ .addReg (ValReg, 0 , SubReg)
2787
+ .getReg (0 );
2788
+ RBI.constrainGenericRegister (Copy, *RC, MRI);
2789
+ LdSt.getOperand (0 ).setReg (Copy);
2790
+ }
2791
+
2774
2792
// Helper lambda for partially selecting I. Either returns the original
2775
2793
// instruction with an updated opcode, or a new instruction.
2776
2794
auto SelectLoadStoreAddressingMode = [&]() -> MachineInstr * {
2777
- bool IsStore = I. getOpcode () == TargetOpcode::G_STORE ;
2795
+ bool IsStore = isa<GStore>(I) ;
2778
2796
const unsigned NewOpc =
2779
2797
selectLoadStoreUIOp (I.getOpcode (), RB.getID (), MemSizeInBits);
2780
2798
if (NewOpc == I.getOpcode ())
@@ -2791,7 +2809,8 @@ bool AArch64InstructionSelector::select(MachineInstr &I) {
2791
2809
2792
2810
// Folded something. Create a new instruction and return it.
2793
2811
auto NewInst = MIB.buildInstr (NewOpc, {}, {}, I.getFlags ());
2794
- IsStore ? NewInst.addUse (ValReg) : NewInst.addDef (ValReg);
2812
+ Register CurValReg = I.getOperand (0 ).getReg ();
2813
+ IsStore ? NewInst.addUse (CurValReg) : NewInst.addDef (CurValReg);
2795
2814
NewInst.cloneMemRefs (I);
2796
2815
for (auto &Fn : *AddrModeFns)
2797
2816
Fn (NewInst);
0 commit comments