MaskRay created this revision. Herald added subscribers: vkmr, frasercrmck, evandro, luismarques, apazos, sameer.abuasal, s.egerton, Jim, benna, psnobl, jocewei, PkmX, the_o, brucehoult, MartinMosbeck, rogfer01, edward-jones, zzheng, jrtc27, shiva0217, kito-cheng, niosHD, sabuasal, simoncook, johnrusso, rbar, asb, hiraditya. MaskRay requested review of this revision. Herald added projects: clang, LLVM. Herald added subscribers: llvm-commits, cfe-commits.
Similar to D46745 <https://reviews.llvm.org/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; } We need 'S' to be documented on GCC: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101275 Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D105254 Files: clang/lib/Basic/Targets/RISCV.cpp clang/test/CodeGen/RISCV/riscv-inline-asm.c llvm/lib/Target/RISCV/RISCVISelLowering.cpp llvm/test/CodeGen/RISCV/inline-asm-S-constraint.ll
Index: llvm/test/CodeGen/RISCV/inline-asm-S-constraint.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/RISCV/inline-asm-S-constraint.ll @@ -0,0 +1,56 @@ +; 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 + +; Function Attrs: nofree nosync nounwind readnone +define dso_local i8* @constraint_S() #1 { +; RV32-LABEL: constraint_S: +; RV32: # %bb.0: # %entry +; 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: # %entry +; RV64-NEXT: #APP +; RV64-NEXT: lui a0, %hi(var) +; RV64-NEXT: addi a0, a0, %lo(var) +; RV64-NEXT: #NO_APP +; RV64-NEXT: ret +entry: + %0 = tail call i8* asm "lui $0, %hi($1)\0Aaddi $0,$0,%lo($1)", "=r,S"(i32* nonnull @var) + ret i8* %0 +} + +; Function Attrs: nofree nosync nounwind readnone +define dso_local i8* @constraint_S_label() #1 { +; 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: ; preds = %entry + %0 = tail call i8* asm "lui $0, %hi($1)\0Aaddi $0,$0,%lo($1)", "=r,S"(i8* blockaddress(@constraint_S_label, %L1)) + ret i8* %0 +} Index: llvm/lib/Target/RISCV/RISCVISelLowering.cpp =================================================================== --- llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -8240,6 +8240,8 @@ return C_Immediate; case 'A': return C_Memory; + case 'S': // A symbolic address + return C_Other; } } return TargetLowering::getConstraintType(Constraint); @@ -8469,6 +8471,16 @@ DAG.getTargetConstant(CVal, SDLoc(Op), Subtarget.getXLenVT())); } return; + case 'S': + if (const GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(Op)) { + Ops.push_back(DAG.getTargetGlobalAddress(GA->getGlobal(), SDLoc(Op), + GA->getValueType(0))); + } else if (const BlockAddressSDNode *BA = + dyn_cast<BlockAddressSDNode>(Op)) { + Ops.push_back(DAG.getTargetBlockAddress(BA->getBlockAddress(), + BA->getValueType(0))); + } + return; default: break; } Index: clang/test/CodeGen/RISCV/riscv-inline-asm.c =================================================================== --- clang/test/CodeGen/RISCV/riscv-inline-asm.c +++ clang/test/CodeGen/RISCV/riscv-inline-asm.c @@ -44,3 +44,9 @@ // 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)); +} Index: clang/lib/Basic/Targets/RISCV.cpp =================================================================== --- clang/lib/Basic/Targets/RISCV.cpp +++ clang/lib/Basic/Targets/RISCV.cpp @@ -87,6 +87,9 @@ // 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') {
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits