22
22
#include " MCTargetDesc/AArch64AddressingModes.h"
23
23
#include " MCTargetDesc/AArch64MCTargetDesc.h"
24
24
#include " llvm/ADT/Optional.h"
25
+ #include " llvm/CodeGen/GlobalISel/GenericMachineInstrs.h"
25
26
#include " llvm/CodeGen/GlobalISel/InstructionSelector.h"
26
27
#include " llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h"
27
28
#include " llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
@@ -2701,29 +2702,29 @@ bool AArch64InstructionSelector::select(MachineInstr &I) {
2701
2702
case TargetOpcode::G_ZEXTLOAD:
2702
2703
case TargetOpcode::G_LOAD:
2703
2704
case TargetOpcode::G_STORE: {
2705
+ GLoadStore &LdSt = cast<GLoadStore>(I);
2704
2706
bool IsZExtLoad = I.getOpcode () == TargetOpcode::G_ZEXTLOAD;
2705
- LLT PtrTy = MRI.getType (I. getOperand ( 1 ). getReg ());
2707
+ LLT PtrTy = MRI.getType (LdSt. getPointerReg ());
2706
2708
2707
2709
if (PtrTy != LLT::pointer (0 , 64 )) {
2708
2710
LLVM_DEBUG (dbgs () << " Load/Store pointer has type: " << PtrTy
2709
2711
<< " , expected: " << LLT::pointer (0 , 64 ) << ' \n ' );
2710
2712
return false ;
2711
2713
}
2712
2714
2713
- auto &MemOp = **I.memoperands_begin ();
2714
- uint64_t MemSizeInBytes = MemOp.getSize ();
2715
- unsigned MemSizeInBits = MemSizeInBytes * 8 ;
2716
- AtomicOrdering Order = MemOp.getSuccessOrdering ();
2715
+ uint64_t MemSizeInBytes = LdSt.getMemSize ();
2716
+ unsigned MemSizeInBits = LdSt.getMemSizeInBits ();
2717
+ AtomicOrdering Order = LdSt.getMMO ().getSuccessOrdering ();
2717
2718
2718
2719
// Need special instructions for atomics that affect ordering.
2719
2720
if (Order != AtomicOrdering::NotAtomic &&
2720
2721
Order != AtomicOrdering::Unordered &&
2721
2722
Order != AtomicOrdering::Monotonic) {
2722
- assert (I. getOpcode () != TargetOpcode::G_ZEXTLOAD );
2723
+ assert (!isa<GZExtLoad>(LdSt) );
2723
2724
if (MemSizeInBytes > 64 )
2724
2725
return false ;
2725
2726
2726
- if (I. getOpcode () == TargetOpcode::G_LOAD ) {
2727
+ if (isa<GLoad>(LdSt) ) {
2727
2728
static unsigned Opcodes[] = {AArch64::LDARB, AArch64::LDARH,
2728
2729
AArch64::LDARW, AArch64::LDARX};
2729
2730
I.setDesc (TII.get (Opcodes[Log2_32 (MemSizeInBytes)]));
@@ -2737,7 +2738,7 @@ bool AArch64InstructionSelector::select(MachineInstr &I) {
2737
2738
}
2738
2739
2739
2740
#ifndef NDEBUG
2740
- const Register PtrReg = I. getOperand ( 1 ). getReg ();
2741
+ const Register PtrReg = LdSt. getPointerReg ();
2741
2742
const RegisterBank &PtrRB = *RBI.getRegBank (PtrReg, MRI, TRI);
2742
2743
// Sanity-check the pointer register.
2743
2744
assert (PtrRB.getID () == AArch64::GPRRegBankID &&
@@ -2746,13 +2747,31 @@ bool AArch64InstructionSelector::select(MachineInstr &I) {
2746
2747
" Load/Store pointer operand isn't a pointer" );
2747
2748
#endif
2748
2749
2749
- const Register ValReg = I.getOperand (0 ).getReg ();
2750
+ const Register ValReg = LdSt.getReg (0 );
2751
+ const LLT ValTy = MRI.getType (ValReg);
2750
2752
const RegisterBank &RB = *RBI.getRegBank (ValReg, MRI, TRI);
2751
2753
2754
+ // The code below doesn't support truncating stores, so we need to split it
2755
+ // again.
2756
+ if (isa<GStore>(LdSt) && ValTy.getSizeInBits () > MemSizeInBits) {
2757
+ unsigned SubReg;
2758
+ LLT MemTy = LdSt.getMMO ().getMemoryType ();
2759
+ auto *RC = getRegClassForTypeOnBank (MemTy, RB, RBI);
2760
+ if (!getSubRegForClass (RC, TRI, SubReg))
2761
+ return false ;
2762
+
2763
+ // Generate a subreg copy.
2764
+ auto Copy = MIB.buildInstr (TargetOpcode::COPY, {MemTy}, {})
2765
+ .addReg (ValReg, 0 , SubReg)
2766
+ .getReg (0 );
2767
+ RBI.constrainGenericRegister (Copy, *RC, MRI);
2768
+ LdSt.getOperand (0 ).setReg (Copy);
2769
+ }
2770
+
2752
2771
// Helper lambda for partially selecting I. Either returns the original
2753
2772
// instruction with an updated opcode, or a new instruction.
2754
2773
auto SelectLoadStoreAddressingMode = [&]() -> MachineInstr * {
2755
- bool IsStore = I. getOpcode () == TargetOpcode::G_STORE ;
2774
+ bool IsStore = isa<GStore>(I) ;
2756
2775
const unsigned NewOpc =
2757
2776
selectLoadStoreUIOp (I.getOpcode (), RB.getID (), MemSizeInBits);
2758
2777
if (NewOpc == I.getOpcode ())
@@ -2769,7 +2788,8 @@ bool AArch64InstructionSelector::select(MachineInstr &I) {
2769
2788
2770
2789
// Folded something. Create a new instruction and return it.
2771
2790
auto NewInst = MIB.buildInstr (NewOpc, {}, {}, I.getFlags ());
2772
- IsStore ? NewInst.addUse (ValReg) : NewInst.addDef (ValReg);
2791
+ Register CurValReg = I.getOperand (0 ).getReg ();
2792
+ IsStore ? NewInst.addUse (CurValReg) : NewInst.addDef (CurValReg);
2773
2793
NewInst.cloneMemRefs (I);
2774
2794
for (auto &Fn : *AddrModeFns)
2775
2795
Fn (NewInst);
0 commit comments