From 793af3b9f0a765912a1a27c473b6514c8108ddca Mon Sep 17 00:00:00 2001 From: Daniel Cederman Date: Fri, 20 Apr 2018 06:57:49 +0000 Subject: [PATCH] [Sparc] Fix addressing mode when using 64-bit values in inline assembly Summary: If a 64-bit register is used as an operand in inline assembly together with a memory reference, the memory addressing will be wrong. The addressing will be a single reg, instead of reg+reg or reg+imm. This will generate a bad offset value or an exception in printMemOperand(). For example: ``` long long int val = 5; long long int mem; __asm__ volatile ("std %1, %0":"=m"(mem):"r"(val)); ``` becomes: ``` std %i0, [%i2+589833] ``` The problem is that SelectInlineAsmMemoryOperand() is never called for the memory references if one of the operands is a 64-bit register. By calling SelectInlineAsmMemoryOperands() in tryInlineAsm() the Sparc version of SelectInlineAsmMemoryOperand() gets called for each memory reference. Reviewers: jyknight, venkatra Reviewed By: jyknight Subscribers: eraman, fedor.sergeev, jrtc27, llvm-commits Differential Revision: https://reviews.llvm.org/D45761 llvm-svn: 330392 --- llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp | 2 ++ llvm/test/CodeGen/SPARC/inlineasm.ll | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp b/llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp index c36e75d..0932cd5 100644 --- a/llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp +++ b/llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp @@ -311,6 +311,8 @@ bool SparcDAGToDAGISel::tryInlineAsm(SDNode *N){ if (!Changed) return false; + SelectInlineAsmMemoryOperands(AsmNodeOperands, SDLoc(N)); + SDValue New = CurDAG->getNode(ISD::INLINEASM, SDLoc(N), CurDAG->getVTList(MVT::Other, MVT::Glue), AsmNodeOperands); New->setNodeId(-1); diff --git a/llvm/test/CodeGen/SPARC/inlineasm.ll b/llvm/test/CodeGen/SPARC/inlineasm.ll index 35a6270..d4584f8 100644 --- a/llvm/test/CodeGen/SPARC/inlineasm.ll +++ b/llvm/test/CodeGen/SPARC/inlineasm.ll @@ -112,3 +112,11 @@ entry: %2 = tail call double asm sideeffect "faddd $1, $2, $0;", "=f,f,e"(double %0, double %1) #7 ret double %2 } + +; CHECK-LABEL: test_addressing_mode_i64: +; CHECK: std %l0, [%o0] +define void @test_addressing_mode_i64(i64* %out) { +entry: + call void asm "std %l0, $0", "=*m,r"(i64* nonnull %out, i64 0) + ret void +} -- 2.7.4