summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorDiana Picus <diana.picus@linaro.org>2018-01-04 10:54:57 +0000
committerDiana Picus <diana.picus@linaro.org>2018-01-04 10:54:57 +0000
commit37ae9f68a404f2684e83d4ad10c051ad7e89b1c8 (patch)
tree93b972760187fe87a6f97632a36bf47877227278 /llvm/lib
parent4d5e34b221d140dfd8829a0050a8a8d84e7a5983 (diff)
downloadbcm5719-llvm-37ae9f68a404f2684e83d4ad10c051ad7e89b1c8.tar.gz
bcm5719-llvm-37ae9f68a404f2684e83d4ad10c051ad7e89b1c8.zip
[ARM GlobalISel] Fix selection of pointer constants
We used to handle G_CONSTANT with pointer type by forcing the type of the result register to s32 and then letting TableGen handle it. Unfortunately, setting the type only works for generic virtual registers, that haven't yet been constrained to a register class (e.g. those used only by a COPY later on). If the result register has already been constrained as a use of a previously selected instruction, then setting the type will assert. It would be nice to be able to teach TableGen to select pointer constants the same as integer constants, but since it's such an edge case (at the moment the only pointer constant that we're generally interested in is 0, and that is mostly used for comparisons and selects, which are also not supported by TableGen) it's probably not worth the effort right now. Instead, handle pointer constants with some trivial handwritten code. llvm-svn: 321793
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/ARM/ARMInstructionSelector.cpp34
1 files changed, 26 insertions, 8 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();
OpenPOWER on IntegriCloud