summaryrefslogtreecommitdiffstats
path: root/llvm/test
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/test')
-rw-r--r--llvm/test/CodeGen/AArch64/GlobalISel/arm64-instructionselect-xor.mir166
-rw-r--r--llvm/test/CodeGen/AArch64/GlobalISel/arm64-instructionselect.mir61
-rw-r--r--llvm/test/TableGen/GlobalISelEmitter.td72
3 files changed, 228 insertions, 71 deletions
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-instructionselect-xor.mir b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-instructionselect-xor.mir
new file mode 100644
index 00000000000..2fd5588cadd
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-instructionselect-xor.mir
@@ -0,0 +1,166 @@
+# RUN: llc -O0 -mtriple=aarch64-apple-ios -run-pass=instruction-select -verify-machineinstrs -global-isel %s -o - | FileCheck %s -check-prefix=CHECK -check-prefix=IOS
+# RUN: llc -O0 -mtriple=aarch64-linux-gnu -run-pass=instruction-select -verify-machineinstrs -global-isel %s -o - | FileCheck %s -check-prefix=CHECK -check-prefix=LINUX-DEFAULT
+# RUN: llc -O0 -mtriple=aarch64-linux-gnu -relocation-model=pic -run-pass=instruction-select -verify-machineinstrs -global-isel %s -o - | FileCheck %s -check-prefix=CHECK -check-prefix=LINUX-PIC
+
+# Test the instruction selector.
+# As we support more instructions, we need to split this up.
+
+--- |
+ target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
+
+ define void @xor_s32_gpr() { ret void }
+ define void @xor_s64_gpr() { ret void }
+ define void @xor_constant_n1_s32_gpr() { ret void }
+ define void @xor_constant_n1_s64_gpr() { ret void }
+ define void @xor_constant_n1_s32_gpr_2bb() { ret void }
+
+...
+
+---
+# Check that we select a 32-bit GPR G_XOR into EORWrr on GPR32.
+# Also check that we constrain the register class of the COPY to GPR32.
+# CHECK-LABEL: name: xor_s32_gpr
+name: xor_s32_gpr
+legalized: true
+regBankSelected: true
+
+# CHECK: registers:
+# CHECK-NEXT: - { id: 0, class: gpr32 }
+# CHECK-NEXT: - { id: 1, class: gpr32 }
+# CHECK-NEXT: - { id: 2, class: gpr32 }
+registers:
+ - { id: 0, class: gpr }
+ - { id: 1, class: gpr }
+ - { id: 2, class: gpr }
+
+# CHECK: body:
+# CHECK: %0 = COPY %w0
+# CHECK: %1 = COPY %w1
+# CHECK: %2 = EORWrr %0, %1
+body: |
+ bb.0:
+ liveins: %w0, %w1
+
+ %0(s32) = COPY %w0
+ %1(s32) = COPY %w1
+ %2(s32) = G_XOR %0, %1
+...
+
+---
+# Same as xor_s64_gpr, for 64-bit operations.
+# CHECK-LABEL: name: xor_s64_gpr
+name: xor_s64_gpr
+legalized: true
+regBankSelected: true
+
+# CHECK: registers:
+# CHECK-NEXT: - { id: 0, class: gpr64 }
+# CHECK-NEXT: - { id: 1, class: gpr64 }
+# CHECK-NEXT: - { id: 2, class: gpr64 }
+registers:
+ - { id: 0, class: gpr }
+ - { id: 1, class: gpr }
+ - { id: 2, class: gpr }
+
+# CHECK: body:
+# CHECK: %0 = COPY %x0
+# CHECK: %1 = COPY %x1
+# CHECK: %2 = EORXrr %0, %1
+body: |
+ bb.0:
+ liveins: %x0, %x1
+
+ %0(s64) = COPY %x0
+ %1(s64) = COPY %x1
+ %2(s64) = G_XOR %0, %1
+...
+
+---
+# Check that we select a 32-bit GPR G_XOR into EORWrr on GPR32.
+# Also check that we constrain the register class of the COPY to GPR32.
+# CHECK-LABEL: name: xor_constant_n1_s32_gpr
+name: xor_constant_n1_s32_gpr
+legalized: true
+regBankSelected: true
+
+# CHECK: registers:
+# CHECK-NEXT: - { id: 0, class: gpr32 }
+# CHECK-NEXT: - { id: 1, class: gpr32 }
+# CHECK-NEXT: - { id: 2, class: gpr32 }
+registers:
+ - { id: 0, class: gpr }
+ - { id: 1, class: gpr }
+ - { id: 2, class: gpr }
+
+# CHECK: body:
+# CHECK: %0 = COPY %w0
+# CHECK: %2 = ORNWrr %wzr, %0
+body: |
+ bb.0:
+ liveins: %w0
+
+ %0(s32) = COPY %w0
+ %1(s32) = G_CONSTANT -1
+ %2(s32) = G_XOR %0, %1
+...
+
+---
+# Same as xor_constant_n1_s64_gpr, for 64-bit operations.
+# CHECK-LABEL: name: xor_constant_n1_s64_gpr
+name: xor_constant_n1_s64_gpr
+legalized: true
+regBankSelected: true
+
+# CHECK: registers:
+# CHECK-NEXT: - { id: 0, class: gpr64 }
+# CHECK-NEXT: - { id: 1, class: gpr64 }
+# CHECK-NEXT: - { id: 2, class: gpr64 }
+registers:
+ - { id: 0, class: gpr }
+ - { id: 1, class: gpr }
+ - { id: 2, class: gpr }
+
+# CHECK: body:
+# CHECK: %0 = COPY %x0
+# CHECK: %2 = ORNXrr %xzr, %0
+body: |
+ bb.0:
+ liveins: %x0
+
+ %0(s64) = COPY %x0
+ %1(s64) = G_CONSTANT -1
+ %2(s64) = G_XOR %0, %1
+...
+
+---
+# Check that we can obtain constants from other basic blocks.
+# CHECK-LABEL: name: xor_constant_n1_s32_gpr_2bb
+name: xor_constant_n1_s32_gpr_2bb
+legalized: true
+regBankSelected: true
+
+# CHECK: registers:
+# CHECK-NEXT: - { id: 0, class: gpr32 }
+# CHECK-NEXT: - { id: 1, class: gpr32 }
+# CHECK-NEXT: - { id: 2, class: gpr32 }
+registers:
+ - { id: 0, class: gpr }
+ - { id: 1, class: gpr }
+ - { id: 2, class: gpr }
+
+# CHECK: body:
+# CHECK: B %bb.1
+# CHECK: %0 = COPY %w0
+# CHECK: %2 = ORNWrr %wzr, %0
+
+body: |
+ bb.0:
+ liveins: %w0, %w1
+ successors: %bb.1
+ %1(s32) = G_CONSTANT -1
+ G_BR %bb.1
+ bb.1:
+ %0(s32) = COPY %w0
+ %2(s32) = G_XOR %0, %1
+...
+
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-instructionselect.mir b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-instructionselect.mir
index 55329aa5b27..879b45bdf6d 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-instructionselect.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-instructionselect.mir
@@ -18,9 +18,6 @@
define void @or_s64_gpr() { ret void }
define void @or_v2s32_fpr() { ret void }
- define void @xor_s32_gpr() { ret void }
- define void @xor_s64_gpr() { ret void }
-
define void @and_s32_gpr() { ret void }
define void @and_s64_gpr() { ret void }
@@ -354,64 +351,6 @@ body: |
...
---
-# Same as add_s32_gpr, for G_XOR operations.
-# CHECK-LABEL: name: xor_s32_gpr
-name: xor_s32_gpr
-legalized: true
-regBankSelected: true
-
-# CHECK: registers:
-# CHECK-NEXT: - { id: 0, class: gpr32 }
-# CHECK-NEXT: - { id: 1, class: gpr32 }
-# CHECK-NEXT: - { id: 2, class: gpr32 }
-registers:
- - { id: 0, class: gpr }
- - { id: 1, class: gpr }
- - { id: 2, class: gpr }
-
-# CHECK: body:
-# CHECK: %0 = COPY %w0
-# CHECK: %1 = COPY %w1
-# CHECK: %2 = EORWrr %0, %1
-body: |
- bb.0:
- liveins: %w0, %w1
-
- %0(s32) = COPY %w0
- %1(s32) = COPY %w1
- %2(s32) = G_XOR %0, %1
-...
-
----
-# Same as add_s64_gpr, for G_XOR operations.
-# CHECK-LABEL: name: xor_s64_gpr
-name: xor_s64_gpr
-legalized: true
-regBankSelected: true
-
-# CHECK: registers:
-# CHECK-NEXT: - { id: 0, class: gpr64 }
-# CHECK-NEXT: - { id: 1, class: gpr64 }
-# CHECK-NEXT: - { id: 2, class: gpr64 }
-registers:
- - { id: 0, class: gpr }
- - { id: 1, class: gpr }
- - { id: 2, class: gpr }
-
-# CHECK: body:
-# CHECK: %0 = COPY %x0
-# CHECK: %1 = COPY %x1
-# CHECK: %2 = EORXrr %0, %1
-body: |
- bb.0:
- liveins: %x0, %x1
-
- %0(s64) = COPY %x0
- %1(s64) = COPY %x1
- %2(s64) = G_XOR %0, %1
-...
-
----
# Same as add_s32_gpr, for G_AND operations.
# CHECK-LABEL: name: and_s32_gpr
name: and_s32_gpr
diff --git a/llvm/test/TableGen/GlobalISelEmitter.td b/llvm/test/TableGen/GlobalISelEmitter.td
index 42a59f92bfa..636fd012fb3 100644
--- a/llvm/test/TableGen/GlobalISelEmitter.td
+++ b/llvm/test/TableGen/GlobalISelEmitter.td
@@ -7,7 +7,7 @@ include "llvm/Target/Target.td"
def MyTargetISA : InstrInfo;
def MyTarget : Target { let InstructionSet = MyTargetISA; }
-def R0 : Register<"r0">;
+def R0 : Register<"r0"> { let Namespace = "MyTarget"; }
def GPR32 : RegisterClass<"MyTarget", [i32], 32, (add R0)>;
class I<dag OOps, dag IOps, list<dag> Pat>
@@ -23,34 +23,86 @@ class I<dag OOps, dag IOps, list<dag> Pat>
// CHECK: bool MyTargetInstructionSelector::selectImpl(MachineInstr &I) const {
// CHECK: const MachineRegisterInfo &MRI = I.getParent()->getParent()->getRegInfo();
-
//===- Test a simple pattern with regclass operands. ----------------------===//
-// CHECK: if ((I.getOpcode() == TargetOpcode::G_ADD) &&
-// CHECK-NEXT: ((/* Operand 0 */ (MRI.getType(I.getOperand(0).getReg()) == (LLT::scalar(32))) &&
+// CHECK-LABEL: if ((I.getOpcode() == TargetOpcode::G_ADD) &&
+// CHECK-NEXT: ((/* dst */ (MRI.getType(I.getOperand(0).getReg()) == (LLT::scalar(32))) &&
// CHECK-NEXT: ((&RBI.getRegBankFromRegClass(MyTarget::GPR32RegClass) == RBI.getRegBank(I.getOperand(0).getReg(), MRI, TRI))))) &&
-// CHECK-NEXT: ((/* Operand 1 */ (MRI.getType(I.getOperand(1).getReg()) == (LLT::scalar(32))) &&
+// CHECK-NEXT: ((/* src1 */ (MRI.getType(I.getOperand(1).getReg()) == (LLT::scalar(32))) &&
// CHECK-NEXT: ((&RBI.getRegBankFromRegClass(MyTarget::GPR32RegClass) == RBI.getRegBank(I.getOperand(1).getReg(), MRI, TRI))))) &&
-// CHECK-NEXT: ((/* Operand 2 */ (MRI.getType(I.getOperand(2).getReg()) == (LLT::scalar(32))) &&
+// CHECK-NEXT: ((/* src2 */ (MRI.getType(I.getOperand(2).getReg()) == (LLT::scalar(32))) &&
// CHECK-NEXT: ((&RBI.getRegBankFromRegClass(MyTarget::GPR32RegClass) == RBI.getRegBank(I.getOperand(2).getReg(), MRI, TRI)))))) {
// CHECK-NEXT: // (add:i32 GPR32:i32:$src1, GPR32:i32:$src2) => (ADD:i32 GPR32:i32:$src1, GPR32:i32:$src2)
// CHECK-NEXT: I.setDesc(TII.get(MyTarget::ADD));
-// CHECK-NEXT: constrainSelectedInstRegOperands(I, TII, TRI, RBI);
+// CHECK-NEXT: MachineInstr &NewI = I;
+// CHECK: constrainSelectedInstRegOperands(NewI, TII, TRI, RBI);
// CHECK-NEXT: return true;
// CHECK-NEXT: }
def ADD : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2),
[(set GPR32:$dst, (add GPR32:$src1, GPR32:$src2))]>;
+// CHECK-LABEL: if ((I.getOpcode() == TargetOpcode::G_MUL) &&
+// CHECK-NEXT: ((/* dst */ (MRI.getType(I.getOperand(0).getReg()) == (LLT::scalar(32))) &&
+// CHECK-NEXT: ((&RBI.getRegBankFromRegClass(MyTarget::GPR32RegClass) == RBI.getRegBank(I.getOperand(0).getReg(), MRI, TRI))))) &&
+// CHECK-NEXT: ((/* src1 */ (MRI.getType(I.getOperand(1).getReg()) == (LLT::scalar(32))) &&
+// CHECK-NEXT: ((&RBI.getRegBankFromRegClass(MyTarget::GPR32RegClass) == RBI.getRegBank(I.getOperand(1).getReg(), MRI, TRI))))) &&
+// CHECK-NEXT: ((/* src2 */ (MRI.getType(I.getOperand(2).getReg()) == (LLT::scalar(32))) &&
+// CHECK-NEXT: ((&RBI.getRegBankFromRegClass(MyTarget::GPR32RegClass) == RBI.getRegBank(I.getOperand(2).getReg(), MRI, TRI)))))) {
+
+// CHECK-NEXT: // (mul:i32 GPR32:i32:$src1, GPR32:i32:$src2) => (MUL:i32 GPR32:i32:$src2, GPR32:i32:$src1)
+// CHECK-NEXT: MachineInstrBuilder MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(MyTarget::MUL));
+// CHECK-NEXT: MIB.add(I.getOperand(0)/*dst*/);
+// CHECK-NEXT: MIB.add(I.getOperand(2)/*src2*/);
+// CHECK-NEXT: MIB.add(I.getOperand(1)/*src1*/);
+// CHECK-NEXT: MIB.setMemRefs(I.memoperands_begin(), I.memoperands_end());
+// CHECK-NEXT: I.eraseFromParent();
+// CHECK-NEXT: MachineInstr &NewI = *MIB;
+// CHECK: constrainSelectedInstRegOperands(NewI, TII, TRI, RBI);
+// CHECK-NEXT: return true;
+// CHECK-NEXT: }
+
+def MUL : I<(outs GPR32:$dst), (ins GPR32:$src2, GPR32:$src1),
+ [(set GPR32:$dst, (mul GPR32:$src1, GPR32:$src2))]>;
+
+//===- Test a simple pattern with constant immediate operands. ------------===//
+//
+// This must precede the 3-register variants because constant immediates have
+// priority over register banks.
+
+// CHECK-LABEL: if ((I.getOpcode() == TargetOpcode::G_XOR) &&
+// CHECK-NEXT: ((/* dst */ (MRI.getType(I.getOperand(0).getReg()) == (LLT::scalar(32))) &&
+// CHECK-NEXT: ((&RBI.getRegBankFromRegClass(MyTarget::GPR32RegClass) == RBI.getRegBank(I.getOperand(0).getReg(), MRI, TRI))))) &&
+// CHECK-NEXT: ((/* Wm */ (MRI.getType(I.getOperand(1).getReg()) == (LLT::scalar(32))) &&
+// CHECK-NEXT: ((&RBI.getRegBankFromRegClass(MyTarget::GPR32RegClass) == RBI.getRegBank(I.getOperand(1).getReg(), MRI, TRI))))) &&
+// CHECK-NEXT: ((/* Operand 2 */ (MRI.getType(I.getOperand(2).getReg()) == (LLT::scalar(32))) &&
+// CHECK-NEXT: (isOperandImmEqual(I.getOperand(2), -1, MRI))))) {
+
+// CHECK-NEXT: // (xor:i32 GPR32:i32:$Wm, -1:i32) => (ORN:i32 R0:i32, GPR32:i32:$Wm)
+// CHECK-NEXT: MachineInstrBuilder MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(MyTarget::ORN));
+// CHECK-NEXT: MIB.add(I.getOperand(0)/*dst*/);
+// CHECK-NEXT: MIB.addReg(MyTarget::R0);
+// CHECK-NEXT: MIB.add(I.getOperand(1)/*Wm*/);
+// CHECK-NEXT: MIB.setMemRefs(I.memoperands_begin(), I.memoperands_end());
+// CHECK-NEXT: I.eraseFromParent();
+// CHECK-NEXT: MachineInstr &NewI = *MIB;
+// CHECK: constrainSelectedInstRegOperands(NewI, TII, TRI, RBI);
+// CHECK-NEXT: return true;
+// CHECK-NEXT: }
+
+def ORN : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2), []>;
+def : Pat<(not GPR32:$Wm), (ORN R0, GPR32:$Wm)>;
+
//===- Test a pattern with an MBB operand. --------------------------------===//
-// CHECK: if ((I.getOpcode() == TargetOpcode::G_BR) &&
-// CHECK-NEXT: ((/* Operand 0 */ (I.getOperand(0).isMBB())))) {
+// CHECK-LABEL: if ((I.getOpcode() == TargetOpcode::G_BR) &&
+// CHECK-NEXT: ((/* target */ (I.getOperand(0).isMBB())))) {
// CHECK-NEXT: // (br (bb:Other):$target) => (BR (bb:Other):$target)
// CHECK-NEXT: I.setDesc(TII.get(MyTarget::BR));
-// CHECK-NEXT: constrainSelectedInstRegOperands(I, TII, TRI, RBI);
+// CHECK-NEXT: MachineInstr &NewI = I;
+// CHECK: constrainSelectedInstRegOperands(NewI, TII, TRI, RBI);
// CHECK-NEXT: return true;
// CHECK-NEXT: }
OpenPOWER on IntegriCloud