summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Target/ARM/ARMInstructionSelector.cpp34
-rw-r--r--llvm/test/CodeGen/ARM/GlobalISel/arm-instruction-select.mir25
2 files changed, 48 insertions, 11 deletions
diff --git a/llvm/lib/Target/ARM/ARMInstructionSelector.cpp b/llvm/lib/Target/ARM/ARMInstructionSelector.cpp
index b0fd0b47692..c4b9d6d25e5 100644
--- a/llvm/lib/Target/ARM/ARMInstructionSelector.cpp
+++ b/llvm/lib/Target/ARM/ARMInstructionSelector.cpp
@@ -670,14 +670,6 @@ bool ARMInstructionSelector::select(MachineInstr &I,
}
using namespace TargetOpcode;
- if (I.getOpcode() == G_CONSTANT) {
- // Pointer constants should be treated the same as 32-bit integer constants.
- // Change the type and let TableGen handle it.
- unsigned ResultReg = I.getOperand(0).getReg();
- LLT Ty = MRI.getType(ResultReg);
- if (Ty.isPointer())
- MRI.setType(ResultReg, LLT::scalar(32));
- }
if (selectImpl(I, CoverageInfo))
return true;
@@ -788,6 +780,32 @@ bool ARMInstructionSelector::select(MachineInstr &I,
I.setDesc(TII.get(COPY));
return selectCopy(I, TII, MRI, TRI, RBI);
}
+ case G_CONSTANT: {
+ if (!MRI.getType(I.getOperand(0).getReg()).isPointer()) {
+ // Non-pointer constants should be handled by TableGen.
+ DEBUG(dbgs() << "Unsupported constant type\n");
+ return false;
+ }
+
+ auto &Val = I.getOperand(1);
+ if (Val.isCImm()) {
+ if (!Val.getCImm()->isZero()) {
+ DEBUG(dbgs() << "Unsupported pointer constant value\n");
+ return false;
+ }
+ Val.ChangeToImmediate(0);
+ } else {
+ assert(Val.isImm() && "Unexpected operand for G_CONSTANT");
+ if (Val.getImm() != 0) {
+ DEBUG(dbgs() << "Unsupported pointer constant value\n");
+ return false;
+ }
+ }
+
+ I.setDesc(TII.get(ARM::MOVi));
+ MIB.add(predOps(ARMCC::AL)).add(condCodeOp());
+ break;
+ }
case G_INTTOPTR:
case G_PTRTOINT: {
auto SrcReg = I.getOperand(1).getReg();
diff --git a/llvm/test/CodeGen/ARM/GlobalISel/arm-instruction-select.mir b/llvm/test/CodeGen/ARM/GlobalISel/arm-instruction-select.mir
index 8b9b83f6d0e..b6db0e0a75f 100644
--- a/llvm/test/CodeGen/ARM/GlobalISel/arm-instruction-select.mir
+++ b/llvm/test/CodeGen/ARM/GlobalISel/arm-instruction-select.mir
@@ -47,7 +47,8 @@
define void @test_gep() { ret void }
define void @test_constant_imm() { ret void }
define void @test_constant_cimm() { ret void }
- define void @test_pointer_constant() { ret void }
+ define void @test_pointer_constant_unconstrained() { ret void }
+ define void @test_pointer_constant_constrained() { ret void }
define void @test_inttoptr_s32() { ret void }
define void @test_ptrtoint_s32() { ret void }
@@ -1110,8 +1111,8 @@ body: |
BX_RET 14, %noreg, implicit %r0
...
---
-name: test_pointer_constant
-# CHECK-LABEL: name: test_pointer_constant
+name: test_pointer_constant_unconstrained
+# CHECK-LABEL: name: test_pointer_constant_unconstrained
legalized: true
regBankSelected: true
selected: false
@@ -1123,10 +1124,28 @@ body: |
%0(p0) = G_CONSTANT i32 0
; CHECK: %[[C:[0-9]+]]:gpr = MOVi 0, 14, %noreg, %noreg
+ ; This leaves %0 unconstrained before the G_CONSTANT is selected.
%r0 = COPY %0(p0)
BX_RET 14, %noreg, implicit %r0
...
---
+name: test_pointer_constant_constrained
+# CHECK-LABEL: name: test_pointer_constant_constrained
+legalized: true
+regBankSelected: true
+selected: false
+# CHECK: selected: true
+registers:
+ - { id: 0, class: gprb }
+body: |
+ bb.0:
+ %0(p0) = G_CONSTANT i32 0
+ ; CHECK: %[[C:[0-9]+]]:gpr = MOVi 0, 14, %noreg, %noreg
+
+ ; This constrains %0 before the G_CONSTANT is selected.
+ G_STORE %0(p0), %0(p0) :: (store 4)
+...
+---
name: test_inttoptr_s32
# CHECK-LABEL: name: test_inttoptr_s32
legalized: true
OpenPOWER on IntegriCloud