diff options
author | Yi Kong <yikong@google.com> | 2017-07-14 21:46:16 +0000 |
---|---|---|
committer | Yi Kong <yikong@google.com> | 2017-07-14 21:46:16 +0000 |
commit | 3b680d8d8113765a5c0a21f9db6e327edfa97f1f (patch) | |
tree | d3efd56741a388c25ba87646e7e5ab88da3f53ca | |
parent | b1e8714af95b03838455f4d46f27c25b8640ddb4 (diff) | |
download | bcm5719-llvm-3b680d8d8113765a5c0a21f9db6e327edfa97f1f.tar.gz bcm5719-llvm-3b680d8d8113765a5c0a21f9db6e327edfa97f1f.zip |
[AArch64] Avoid selecting XZR inline ASM memory operand
Restricting register class to PointerRegClass for memory operands.
Also fix the PointerRegClass for AArch64 from GPR64 to GPR64sp, since
XZR cannot hold a memory pointer while SP is.
Fixes PR33134.
Differential Revision: https://reviews.llvm.org/D34999
llvm-svn: 308060
-rw-r--r-- | llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp | 15 | ||||
-rw-r--r-- | llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp | 2 | ||||
-rw-r--r-- | llvm/test/CodeGen/AArch64/arm64-inline-asm.ll | 10 |
3 files changed, 22 insertions, 5 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp b/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp index 04687847c1a..06005f6b688 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp @@ -239,10 +239,17 @@ bool AArch64DAGToDAGISel::SelectInlineAsmMemoryOperand( case InlineAsm::Constraint_i: case InlineAsm::Constraint_m: case InlineAsm::Constraint_Q: - // Require the address to be in a register. That is safe for all AArch64 - // variants and it is hard to do anything much smarter without knowing - // how the operand is used. - OutOps.push_back(Op); + // We need to make sure that this one operand does not end up in XZR, thus + // require the address to be in a PointerRegClass register. + const TargetRegisterInfo *TRI = Subtarget->getRegisterInfo(); + const TargetRegisterClass *TRC = TRI->getPointerRegClass(*MF); + SDLoc dl(Op); + SDValue RC = CurDAG->getTargetConstant(TRC->getID(), dl, MVT::i64); + SDValue NewOp = + SDValue(CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, + dl, Op.getValueType(), + Op, RC), 0); + OutOps.push_back(NewOp); return false; } return true; diff --git a/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp b/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp index fab92e139dd..2d630c4b1e2 100644 --- a/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp @@ -167,7 +167,7 @@ bool AArch64RegisterInfo::isConstantPhysReg(unsigned PhysReg) const { const TargetRegisterClass * AArch64RegisterInfo::getPointerRegClass(const MachineFunction &MF, unsigned Kind) const { - return &AArch64::GPR64RegClass; + return &AArch64::GPR64spRegClass; } const TargetRegisterClass * diff --git a/llvm/test/CodeGen/AArch64/arm64-inline-asm.ll b/llvm/test/CodeGen/AArch64/arm64-inline-asm.ll index f849df2a51e..848b87fd2cf 100644 --- a/llvm/test/CodeGen/AArch64/arm64-inline-asm.ll +++ b/llvm/test/CodeGen/AArch64/arm64-inline-asm.ll @@ -261,3 +261,13 @@ define void @test_inline_modifier_a(i8* %ptr) nounwind { ; CHECK: prfm pldl1keep, [x0] ret void } + +; PR33134 +define void @test_zero_address() { +entry: +; CHECK-LABEL: test_zero_address +; CHECK: mov {{x[0-9]+}}, xzr +; CHECK: ldr {{x[0-9]+}}, {{[x[0-9]+]}} + tail call i32 asm sideeffect "ldr $0, $1 \0A", "=r,*Q"(i32* null) + ret void +} |