Author: Fangrui Song Date: 2021-07-13T09:30:09-07:00 New Revision: 3d89fb4d13bc3af1c3643a310b90fce51a649119
URL: https://github.com/llvm/llvm-project/commit/3d89fb4d13bc3af1c3643a310b90fce51a649119 DIFF: https://github.com/llvm/llvm-project/commit/3d89fb4d13bc3af1c3643a310b90fce51a649119.diff LOG: [RISCV] Support machine constraint "S" Similar to D46745, "S" represents an absolute symbolic operand, which can be used to specify the access models, e.g. extern int var; void *addr_via_asm() { void *ret; asm("lui %0, %%hi(%1)\naddi %0,%0,%%lo(%1)" : "=r"(ret) : "S"(&var)); return ret; } 'S' is documented in trunk GCC: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101275 Reviewed By: luismarques Differential Revision: https://reviews.llvm.org/D105254 Added: llvm/test/CodeGen/RISCV/inline-asm-S-constraint.ll Modified: clang/lib/Basic/Targets/RISCV.cpp clang/test/CodeGen/RISCV/riscv-inline-asm.c llvm/lib/Target/RISCV/RISCVISelLowering.cpp Removed: ################################################################################ diff --git a/clang/lib/Basic/Targets/RISCV.cpp b/clang/lib/Basic/Targets/RISCV.cpp index 1f31f471db3a4..9705129b39d8f 100644 --- a/clang/lib/Basic/Targets/RISCV.cpp +++ b/clang/lib/Basic/Targets/RISCV.cpp @@ -87,6 +87,9 @@ bool RISCVTargetInfo::validateAsmConstraint( // An address that is held in a general-purpose register. Info.setAllowsMemory(); return true; + case 'S': // A symbolic address + Info.setAllowsRegister(); + return true; case 'v': // A vector register. if (Name[1] == 'r' || Name[1] == 'm') { diff --git a/clang/test/CodeGen/RISCV/riscv-inline-asm.c b/clang/test/CodeGen/RISCV/riscv-inline-asm.c index dea900f1afc0b..2303293876920 100644 --- a/clang/test/CodeGen/RISCV/riscv-inline-asm.c +++ b/clang/test/CodeGen/RISCV/riscv-inline-asm.c @@ -44,3 +44,9 @@ void test_A(int *p) { // CHECK: call void asm sideeffect "", "*A"(i32* %p) asm volatile("" :: "A"(*p)); } + +void test_S() { +// CHECK-LABEL: define{{.*}} void @test_S() +// CHECK: call void asm sideeffect "", "S"(float* nonnull @f) + asm volatile("" :: "S"(&f)); +} diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index ab0d018d345aa..a81aec185cb47 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -8294,6 +8294,8 @@ RISCVTargetLowering::getConstraintType(StringRef Constraint) const { return C_Immediate; case 'A': return C_Memory; + case 'S': // A symbolic address + return C_Other; } } return TargetLowering::getConstraintType(Constraint); @@ -8523,6 +8525,15 @@ void RISCVTargetLowering::LowerAsmOperandForConstraint( DAG.getTargetConstant(CVal, SDLoc(Op), Subtarget.getXLenVT())); } return; + case 'S': + if (const auto *GA = dyn_cast<GlobalAddressSDNode>(Op)) { + Ops.push_back(DAG.getTargetGlobalAddress(GA->getGlobal(), SDLoc(Op), + GA->getValueType(0))); + } else if (const auto *BA = dyn_cast<BlockAddressSDNode>(Op)) { + Ops.push_back(DAG.getTargetBlockAddress(BA->getBlockAddress(), + BA->getValueType(0))); + } + return; default: break; } diff --git a/llvm/test/CodeGen/RISCV/inline-asm-S-constraint.ll b/llvm/test/CodeGen/RISCV/inline-asm-S-constraint.ll new file mode 100644 index 0000000000000..2387978e76144 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/inline-asm-S-constraint.ll @@ -0,0 +1,54 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=riscv32 < %s | FileCheck %s --check-prefix=RV32 +; RUN: llc -mtriple=riscv64 < %s | FileCheck %s --check-prefix=RV64 + +@var = external dso_local global i32, align 4 + +define dso_local i8* @constraint_S() { +; RV32-LABEL: constraint_S: +; RV32: # %bb.0: +; RV32-NEXT: #APP +; RV32-NEXT: lui a0, %hi(var) +; RV32-NEXT: addi a0, a0, %lo(var) +; RV32-NEXT: #NO_APP +; RV32-NEXT: ret +; +; RV64-LABEL: constraint_S: +; RV64: # %bb.0: +; RV64-NEXT: #APP +; RV64-NEXT: lui a0, %hi(var) +; RV64-NEXT: addi a0, a0, %lo(var) +; RV64-NEXT: #NO_APP +; RV64-NEXT: ret + %ret = tail call i8* asm "lui $0, %hi($1)\0Aaddi $0, $0, %lo($1)", "=r,S"(i32* nonnull @var) + ret i8* %ret +} + +; Function Attrs: nofree nosync nounwind readnone +define dso_local i8* @constraint_S_label() { +; RV32-LABEL: constraint_S_label: +; RV32: # %bb.0: # %entry +; RV32-NEXT: .Ltmp0: # Block address taken +; RV32-NEXT: # %bb.1: # %L1 +; RV32-NEXT: #APP +; RV32-NEXT: lui a0, %hi(.Ltmp0) +; RV32-NEXT: addi a0, a0, %lo(.Ltmp0) +; RV32-NEXT: #NO_APP +; RV32-NEXT: ret +; +; RV64-LABEL: constraint_S_label: +; RV64: # %bb.0: # %entry +; RV64-NEXT: .Ltmp0: # Block address taken +; RV64-NEXT: # %bb.1: # %L1 +; RV64-NEXT: #APP +; RV64-NEXT: lui a0, %hi(.Ltmp0) +; RV64-NEXT: addi a0, a0, %lo(.Ltmp0) +; RV64-NEXT: #NO_APP +; RV64-NEXT: ret +entry: + br label %L1 + +L1: + %ret = tail call i8* asm "lui $0, %hi($1)\0Aaddi $0, $0, %lo($1)", "=r,S"(i8* blockaddress(@constraint_S_label, %L1)) + ret i8* %ret +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits