From 94c26701183aca7a85eae6eb52f730bbb0cf78e0 Mon Sep 17 00:00:00 2001 From: Simon Atanasyan Date: Wed, 17 Jul 2019 08:11:15 +0000 Subject: [PATCH] [mips] Support the "o" inline asm constraint As well as other LLVM targets we do not handle "offsettable" memory addresses in any special way. In other words, the "o" constraint is an exact equivalent of the "m" one. But some existing code require the "o" constraint support. This fixes PR42589. Differential Revision: https://reviews.llvm.org/D64792 llvm-svn: 366299 --- lib/Target/Mips/MipsISelLowering.h | 2 + lib/Target/Mips/MipsSEISelDAGToDAG.cpp | 1 + test/CodeGen/Mips/inlineasm_constraint_o.ll | 61 +++++++++++++++++++++ 3 files changed, 64 insertions(+) create mode 100644 test/CodeGen/Mips/inlineasm_constraint_o.ll diff --git a/lib/Target/Mips/MipsISelLowering.h b/lib/Target/Mips/MipsISelLowering.h index 27bf18c8ba9..2db60e9801f 100644 --- a/lib/Target/Mips/MipsISelLowering.h +++ b/lib/Target/Mips/MipsISelLowering.h @@ -653,6 +653,8 @@ class TargetRegisterClass; unsigned getInlineAsmMemConstraint(StringRef ConstraintCode) const override { + if (ConstraintCode == "o") + return InlineAsm::Constraint_o; if (ConstraintCode == "R") return InlineAsm::Constraint_R; if (ConstraintCode == "ZC") diff --git a/lib/Target/Mips/MipsSEISelDAGToDAG.cpp b/lib/Target/Mips/MipsSEISelDAGToDAG.cpp index c50e4c215a4..703f99f37dd 100644 --- a/lib/Target/Mips/MipsSEISelDAGToDAG.cpp +++ b/lib/Target/Mips/MipsSEISelDAGToDAG.cpp @@ -1237,6 +1237,7 @@ SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID, OutOps.push_back(CurDAG->getTargetConstant(0, SDLoc(Op), MVT::i32)); return false; case InlineAsm::Constraint_m: + case InlineAsm::Constraint_o: if (selectAddrRegImm16(Op, Base, Offset)) { OutOps.push_back(Base); OutOps.push_back(Offset); diff --git a/test/CodeGen/Mips/inlineasm_constraint_o.ll b/test/CodeGen/Mips/inlineasm_constraint_o.ll new file mode 100644 index 00000000000..de677cbcc68 --- /dev/null +++ b/test/CodeGen/Mips/inlineasm_constraint_o.ll @@ -0,0 +1,61 @@ +; RUN: llc -march=mipsel -relocation-model=pic < %s | FileCheck %s + +@data = global [8193 x i32] zeroinitializer + +define void @o(i32 *%p) nounwind { +entry: + ; CHECK-LABEL: o: + + call void asm sideeffect "lw $$1, $0", "*o,~{$1}"(i32* getelementptr inbounds ([8193 x i32], [8193 x i32]* @data, i32 0, i32 0)) + + ; CHECK: lw $[[BASEPTR:[0-9]+]], %got(data)( + ; CHECK: #APP + ; CHECK: lw $1, 0($[[BASEPTR]]) + ; CHECK: #NO_APP + + ret void +} + +define void @o_offset_4(i32 *%p) nounwind { +entry: + ; CHECK-LABEL: o_offset_4: + + call void asm sideeffect "lw $$1, $0", "*o,~{$1}"(i32* getelementptr inbounds ([8193 x i32], [8193 x i32]* @data, i32 0, i32 1)) + + ; CHECK: lw $[[BASEPTR:[0-9]+]], %got(data)( + ; CHECK: #APP + ; CHECK: lw $1, 4($[[BASEPTR]]) + ; CHECK: #NO_APP + + ret void +} + +define void @o_offset_32764(i32 *%p) nounwind { +entry: + ; CHECK-LABEL: o_offset_32764: + + call void asm sideeffect "lw $$1, $0", "*o,~{$1}"(i32* getelementptr inbounds ([8193 x i32], [8193 x i32]* @data, i32 0, i32 8191)) + + ; CHECK-DAG: lw $[[BASEPTR:[0-9]+]], %got(data)( + ; CHECK: #APP + ; CHECK: lw $1, 32764($[[BASEPTR]]) + ; CHECK: #NO_APP + + ret void +} + +define void @o_offset_32768(i32 *%p) nounwind { +entry: + ; CHECK-LABEL: o_offset_32768: + + call void asm sideeffect "lw $$1, $0", "*o,~{$1}"(i32* getelementptr inbounds ([8193 x i32], [8193 x i32]* @data, i32 0, i32 8192)) + + ; CHECK-DAG: lw $[[BASEPTR:[0-9]+]], %got(data)( + ; CHECK-DAG: ori $[[T0:[0-9]+]], $zero, 32768 + ; CHECK: addu $[[BASEPTR2:[0-9]+]], $[[BASEPTR]], $[[T0]] + ; CHECK: #APP + ; CHECK: lw $1, 0($[[BASEPTR2]]) + ; CHECK: #NO_APP + + ret void +}