From 26e41a80d07c475fec75e7d58b6408b92161b93a Mon Sep 17 00:00:00 2001 From: wangpc Date: Tue, 6 Jun 2023 17:49:58 +0800 Subject: [PATCH] [RISCV] Handle "o" inline asm memory constraint This is the same as D100412. We just found the same crash when we tried to compile some packages like mariadb, php, etc. For constraint "o", it means "A memory operand is allowed, but only if the address is offsettable". So I think it can be handled just like constraint "m" for RISCV target. And we print verbose information when unsupported constraints occur. Reviewed By: asb Differential Revision: https://reviews.llvm.org/D151979 --- llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp | 4 ++- llvm/test/CodeGen/RISCV/inline-asm.ll | 53 +++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp index 8981e4e..14f3e53 100644 --- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp @@ -2128,6 +2128,7 @@ bool RISCVDAGToDAGISel::SelectInlineAsmMemoryOperand( // Always produce a register and immediate operand, as expected by // RISCVAsmPrinter::PrintAsmMemoryOperand. switch (ConstraintID) { + case InlineAsm::Constraint_o: case InlineAsm::Constraint_m: { SDValue Op0, Op1; bool Found = SelectAddrRegImm(Op, Op0, Op1); @@ -2143,7 +2144,8 @@ bool RISCVDAGToDAGISel::SelectInlineAsmMemoryOperand( CurDAG->getTargetConstant(0, SDLoc(Op), Subtarget->getXLenVT())); return false; default: - break; + report_fatal_error("Unexpected asm memory constraint " + + InlineAsm::getMemConstraintName(ConstraintID)); } return true; diff --git a/llvm/test/CodeGen/RISCV/inline-asm.ll b/llvm/test/CodeGen/RISCV/inline-asm.ll index d653b7a..4cdec57 100644 --- a/llvm/test/CodeGen/RISCV/inline-asm.ll +++ b/llvm/test/CodeGen/RISCV/inline-asm.ll @@ -101,6 +101,59 @@ define i32 @constraint_m_with_offset(ptr %a) nounwind { ret i32 %2 } +define void @constraint_o(ptr %a) nounwind { +; RV32I-LABEL: constraint_o: +; RV32I: # %bb.0: +; RV32I-NEXT: #APP +; RV32I-NEXT: #NO_APP +; RV32I-NEXT: ret +; +; RV64I-LABEL: constraint_o: +; RV64I: # %bb.0: +; RV64I-NEXT: #APP +; RV64I-NEXT: #NO_APP +; RV64I-NEXT: ret + call void asm sideeffect "", "=*o"(ptr elementtype(i32) %a) + ret void +} + +define i32 @constraint_o2(ptr %a) nounwind { +; RV32I-LABEL: constraint_o2: +; RV32I: # %bb.0: +; RV32I-NEXT: #APP +; RV32I-NEXT: lw a0, 0(a0) +; RV32I-NEXT: #NO_APP +; RV32I-NEXT: ret +; +; RV64I-LABEL: constraint_o2: +; RV64I: # %bb.0: +; RV64I-NEXT: #APP +; RV64I-NEXT: lw a0, 0(a0) +; RV64I-NEXT: #NO_APP +; RV64I-NEXT: ret + %1 = tail call i32 asm "lw $0, $1", "=r,*o"(ptr elementtype(i32) %a) + ret i32 %1 +} + +define i32 @constraint_o_with_offset(ptr %a) nounwind { +; RV32I-LABEL: constraint_o_with_offset: +; RV32I: # %bb.0: +; RV32I-NEXT: #APP +; RV32I-NEXT: lw a0, 4(a0) +; RV32I-NEXT: #NO_APP +; RV32I-NEXT: ret +; +; RV64I-LABEL: constraint_o_with_offset: +; RV64I: # %bb.0: +; RV64I-NEXT: #APP +; RV64I-NEXT: lw a0, 4(a0) +; RV64I-NEXT: #NO_APP +; RV64I-NEXT: ret + %1 = getelementptr i32, ptr %a, i32 1 + %2 = tail call i32 asm "lw $0, $1", "=r,*o"(ptr elementtype(i32) %1) + ret i32 %2 +} + define void @constraint_I() nounwind { ; RV32I-LABEL: constraint_I: ; RV32I: # %bb.0: -- 2.7.4