From dbd47c4489b1680b0753c30745588c6248a8b448 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Mon, 10 Jul 2023 13:11:08 -0700 Subject: [PATCH] [RISCV] Don't allow X0 to be used for 'r' constraint in inline assembly Some instructions treat x0 as a special encoding rather than as a value of 0. Since we don't parse the inline assembly to know what the instruction is, chooser the safest option of never using x0. Fixes #63747. Reviewed By: asb Differential Revision: https://reviews.llvm.org/D154744 --- llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 2 +- llvm/test/CodeGen/RISCV/inline-asm.ll | 27 +++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index abc81541887917..9a79426d23ac49 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -15845,7 +15845,7 @@ RISCVTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, // TODO: Support fixed vectors up to XLen for P extension? if (VT.isVector()) break; - return std::make_pair(0U, &RISCV::GPRRegClass); + return std::make_pair(0U, &RISCV::GPRNoX0RegClass); case 'f': if (Subtarget.hasStdExtZfhOrZfhmin() && VT == MVT::f16) return std::make_pair(0U, &RISCV::FPR16RegClass); diff --git a/llvm/test/CodeGen/RISCV/inline-asm.ll b/llvm/test/CodeGen/RISCV/inline-asm.ll index 4cdec5729400a4..2c808c2a699b71 100644 --- a/llvm/test/CodeGen/RISCV/inline-asm.ll +++ b/llvm/test/CodeGen/RISCV/inline-asm.ll @@ -29,6 +29,33 @@ define i32 @constraint_r(i32 %a) nounwind { ret i32 %2 } +; Don't allow 'x0' for 'r'. Some instructions have a different behavior when +; x0 is encoded. +define i32 @constraint_r_zero(i32 %a) nounwind { +; RV32I-LABEL: constraint_r_zero: +; RV32I: # %bb.0: +; RV32I-NEXT: lui a0, %hi(gi) +; RV32I-NEXT: lw a0, %lo(gi)(a0) +; RV32I-NEXT: li a1, 0 +; RV32I-NEXT: #APP +; RV32I-NEXT: add a0, a1, a0 +; RV32I-NEXT: #NO_APP +; RV32I-NEXT: ret +; +; RV64I-LABEL: constraint_r_zero: +; RV64I: # %bb.0: +; RV64I-NEXT: lui a0, %hi(gi) +; RV64I-NEXT: lw a0, %lo(gi)(a0) +; RV64I-NEXT: li a1, 0 +; RV64I-NEXT: #APP +; RV64I-NEXT: add a0, a1, a0 +; RV64I-NEXT: #NO_APP +; RV64I-NEXT: ret + %1 = load i32, ptr @gi + %2 = tail call i32 asm "add $0, $1, $2", "=r,r,r"(i32 0, i32 %1) + ret i32 %2 +} + define i32 @constraint_i(i32 %a) nounwind { ; RV32I-LABEL: constraint_i: ; RV32I: # %bb.0: