[llvm] r277171 - [AArch64][GlobalISel] Select G_LOAD/G_STORE.
Ahmed Bougacha via llvm-commits
llvm-commits at lists.llvm.org
Fri Jul 29 09:56:17 PDT 2016
Author: ab
Date: Fri Jul 29 11:56:16 2016
New Revision: 277171
URL: http://llvm.org/viewvc/llvm-project?rev=277171&view=rev
Log:
[AArch64][GlobalISel] Select G_LOAD/G_STORE.
Mostly straightforward as we ignore addressing modes and just
use the base + unsigned immediate offset (always 0) variants.
This currently fails to select extloads because we have yet to
agree on a representation.
Modified:
llvm/trunk/lib/CodeGen/GlobalISel/InstructionSelector.cpp
llvm/trunk/lib/Target/AArch64/AArch64InstructionSelector.cpp
llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-instructionselect.mir
Modified: llvm/trunk/lib/CodeGen/GlobalISel/InstructionSelector.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/InstructionSelector.cpp?rev=277171&r1=277170&r2=277171&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/GlobalISel/InstructionSelector.cpp (original)
+++ llvm/trunk/lib/CodeGen/GlobalISel/InstructionSelector.cpp Fri Jul 29 11:56:16 2016
@@ -31,9 +31,13 @@ bool InstructionSelector::constrainSelec
for (unsigned OpI = 0, OpE = I.getNumExplicitOperands(); OpI != OpE; ++OpI) {
MachineOperand &MO = I.getOperand(OpI);
- DEBUG(dbgs() << "Converting operand: " << MO << '\n');
- assert(MO.isReg() && "Unsupported binop non-reg operand");
+ // There's nothing to be done on immediates.
+ if (MO.isImm())
+ continue;
+
+ DEBUG(dbgs() << "Converting operand: " << MO << '\n');
+ assert(MO.isReg() && "Unsupported non-reg operand");
const TargetRegisterClass *RC = TII.getRegClass(I.getDesc(), OpI, &TRI, MF);
assert(RC && "Selected inst should have regclass operand");
Modified: llvm/trunk/lib/Target/AArch64/AArch64InstructionSelector.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64InstructionSelector.cpp?rev=277171&r1=277170&r2=277171&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64InstructionSelector.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64InstructionSelector.cpp Fri Jul 29 11:56:16 2016
@@ -79,6 +79,26 @@ static unsigned selectBinaryOp(unsigned
return GenericOpc;
}
+/// Select the AArch64 opcode for the G_LOAD or G_STORE operation \p GenericOpc,
+/// appropriate for the (value) register bank \p RegBankID and of memory access
+/// size \p OpSize. This returns the variant with the base+unsigned-immediate
+/// addressing mode (e.g., LDRXui).
+/// \returns \p GenericOpc if the combination is unsupported.
+static unsigned selectLoadStoreUIOp(unsigned GenericOpc, unsigned RegBankID,
+ unsigned OpSize) {
+ const bool isStore = GenericOpc == TargetOpcode::G_STORE;
+ switch (RegBankID) {
+ case AArch64::GPRRegBankID:
+ switch (OpSize) {
+ case 32:
+ return isStore ? AArch64::STRWui : AArch64::LDRWui;
+ case 64:
+ return isStore ? AArch64::STRXui : AArch64::LDRXui;
+ }
+ };
+ return GenericOpc;
+}
+
bool AArch64InstructionSelector::select(MachineInstr &I) const {
assert(I.getParent() && "Instruction should be in a basic block!");
assert(I.getParent()->getParent() && "Instruction should be in a function!");
@@ -109,6 +129,42 @@ bool AArch64InstructionSelector::select(
return true;
}
+ case TargetOpcode::G_LOAD:
+ case TargetOpcode::G_STORE: {
+ LLT MemTy = I.getType(0);
+ LLT PtrTy = I.getType(1);
+
+ if (PtrTy != LLT::pointer(0)) {
+ DEBUG(dbgs() << "Load/Store pointer has type: " << PtrTy
+ << ", expected: " << LLT::pointer(0) << '\n');
+ return false;
+ }
+
+#ifndef NDEBUG
+ // Sanity-check the pointer register.
+ const unsigned PtrReg = I.getOperand(1).getReg();
+ const RegisterBank &PtrRB = *RBI.getRegBank(PtrReg, MRI, TRI);
+ assert(PtrRB.getID() == AArch64::GPRRegBankID &&
+ "Load/Store pointer operand isn't a GPR");
+ assert(MRI.getSize(PtrReg) == 64 &&
+ "Load/Store pointer operand isn't 64-bit");
+#endif
+
+ const unsigned ValReg = I.getOperand(0).getReg();
+ const RegisterBank &RB = *RBI.getRegBank(ValReg, MRI, TRI);
+
+ const unsigned NewOpc =
+ selectLoadStoreUIOp(I.getOpcode(), RB.getID(), MemTy.getSizeInBits());
+ if (NewOpc == I.getOpcode())
+ return false;
+
+ I.setDesc(TII.get(NewOpc));
+ I.removeTypes();
+
+ I.addOperand(MachineOperand::CreateImm(0));
+ return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
+ }
+
case TargetOpcode::G_OR:
case TargetOpcode::G_AND:
case TargetOpcode::G_ADD:
Modified: llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-instructionselect.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-instructionselect.mir?rev=277171&r1=277170&r2=277171&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-instructionselect.mir (original)
+++ llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-instructionselect.mir Fri Jul 29 11:56:16 2016
@@ -22,6 +22,12 @@
define void @unconditional_br() { ret void }
+ define void @load_s64_gpr(i64* %addr) { ret void }
+ define void @load_s32_gpr(i32* %addr) { ret void }
+
+ define void @store_s64_gpr(i64* %addr) { ret void }
+ define void @store_s32_gpr(i32* %addr) { ret void }
+
...
---
@@ -232,3 +238,103 @@ body: |
G_BR unsized %bb.0
...
+
+---
+# CHECK-LABEL: name: load_s64_gpr
+name: load_s64_gpr
+isSSA: true
+
+# CHECK: registers:
+# CHECK-NEXT: - { id: 0, class: gpr64sp }
+# CHECK-NEXT: - { id: 1, class: gpr64 }
+registers:
+ - { id: 0, class: gpr }
+ - { id: 1, class: gpr }
+
+# CHECK: body:
+# CHECK: %0 = COPY %x0
+# CHECK: %1 = LDRXui %0, 0 :: (load 8 from %ir.addr)
+body: |
+ bb.0:
+ liveins: %x0
+
+ %0(64) = COPY %x0
+ %1(64) = G_LOAD { s64, p0 } %0 :: (load 8 from %ir.addr)
+
+...
+
+---
+# CHECK-LABEL: name: load_s32_gpr
+name: load_s32_gpr
+isSSA: true
+
+# CHECK: registers:
+# CHECK-NEXT: - { id: 0, class: gpr64sp }
+# CHECK-NEXT: - { id: 1, class: gpr32 }
+registers:
+ - { id: 0, class: gpr }
+ - { id: 1, class: gpr }
+
+# CHECK: body:
+# CHECK: %0 = COPY %x0
+# CHECK: %1 = LDRWui %0, 0 :: (load 4 from %ir.addr)
+body: |
+ bb.0:
+ liveins: %x0
+
+ %0(64) = COPY %x0
+ %1(32) = G_LOAD { s32, p0 } %0 :: (load 4 from %ir.addr)
+
+...
+
+---
+# CHECK-LABEL: name: store_s64_gpr
+name: store_s64_gpr
+isSSA: true
+
+# CHECK: registers:
+# CHECK-NEXT: - { id: 0, class: gpr64sp }
+# CHECK-NEXT: - { id: 1, class: gpr64 }
+registers:
+ - { id: 0, class: gpr }
+ - { id: 1, class: gpr }
+
+# CHECK: body:
+# CHECK: %0 = COPY %x0
+# CHECK: %1 = COPY %x1
+# CHECK: STRXui %1, %0, 0 :: (store 8 into %ir.addr)
+body: |
+ bb.0:
+ liveins: %x0, %x1
+
+ %0(64) = COPY %x0
+ %1(64) = COPY %x1
+ G_STORE { s64, p0 } %1, %0 :: (store 8 into %ir.addr)
+
+...
+
+---
+# CHECK-LABEL: name: store_s32_gpr
+name: store_s32_gpr
+isSSA: true
+
+# CHECK: registers:
+# CHECK-NEXT: - { id: 0, class: gpr64sp }
+# CHECK-NEXT: - { id: 1, class: gpr32 }
+registers:
+ - { id: 0, class: gpr }
+ - { id: 1, class: gpr }
+
+# CHECK: body:
+# CHECK: %0 = COPY %x0
+# CHECK: %1 = COPY %w1
+# CHECK: STRWui %1, %0, 0 :: (store 4 into %ir.addr)
+body: |
+ bb.0:
+ liveins: %x0, %w1
+
+ %0(64) = COPY %x0
+ %1(32) = COPY %w1
+ G_STORE { s32, p0 } %1, %0 :: (store 4 into %ir.addr)
+
+...
More information about the llvm-commits
mailing list