[llvm-branch-commits] [llvm][lld][RISCV] Support x3_reg_usage (PR #84598)

via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Fri Mar 8 19:12:45 PST 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-lld-elf

@llvm/pr-subscribers-lld

Author: Paul Kirth (ilovepi)

<details>
<summary>Changes</summary>

This patch adds basic support for the Tag_RISCV_x3_reg_usage attribute
specified in:
https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-elf.adoc#tag_riscv_x3_reg_usage-16-uleb128value
It adds support for merging the x3_reg_usage attribute in the linker,
and basic support for the attribute in attribute parser.

Enabling this feature will allow targets to avoid challenges with mixing
object files with different expectations for how x3/gp is used.

Merging x3_reg_usage tags with different values is considered an error,
with one exception. The value 0 can merge with 1 or 2 value. After the
merge, the resulting value will be the non-zero one.


---
Full diff: https://github.com/llvm/llvm-project/pull/84598.diff


9 Files Affected:

- (modified) lld/ELF/Arch/RISCV.cpp (+12) 
- (modified) lld/test/ELF/riscv-attributes.s (+51) 
- (modified) llvm/include/llvm/Support/RISCVAttributeParser.h (+1) 
- (modified) llvm/include/llvm/Support/RISCVAttributes.h (+10) 
- (modified) llvm/lib/Support/RISCVAttributeParser.cpp (+7) 
- (modified) llvm/lib/Support/RISCVAttributes.cpp (+1) 
- (modified) llvm/test/CodeGen/RISCV/attributes.ll (+5) 
- (modified) llvm/test/MC/RISCV/attribute.s (+3) 
- (modified) llvm/test/MC/RISCV/invalid-attribute.s (+3) 


``````````diff
diff --git a/lld/ELF/Arch/RISCV.cpp b/lld/ELF/Arch/RISCV.cpp
index e44583fb80fd31..f3b134144b654b 100644
--- a/lld/ELF/Arch/RISCV.cpp
+++ b/lld/ELF/Arch/RISCV.cpp
@@ -1224,6 +1224,18 @@ mergeAttributesSection(const SmallVector<InputSectionBase *, 0> &sections) {
           }
         }
         continue;
+
+      case llvm::RISCVAttrs::AttrType::X3_REG_USAGE:
+        if (auto i = parser.getAttributeValue(tag.attr)) {
+          auto r = merged.intAttr.try_emplace(tag.attr, *i);
+          if (r.second) {
+            firstX3RegUse = sec;
+          } else {
+            mergeX3RegUse(merged.intAttr, firstX3RegUse, sec,
+                          r.first->getSecond(), *i);
+          }
+        }
+        continue;
       }
 
       // Fallback for deprecated priv_spec* and other unknown attributes: retain
diff --git a/lld/test/ELF/riscv-attributes.s b/lld/test/ELF/riscv-attributes.s
index 964fec43b52847..43438b238b5d6b 100644
--- a/lld/test/ELF/riscv-attributes.s
+++ b/lld/test/ELF/riscv-attributes.s
@@ -68,6 +68,23 @@
 # RUN: ld.lld atomic_abi_unknown.o atomic_abi_A7.o -o atomic_abi_A7_unknown
 # RUN: llvm-readobj -A atomic_abi_A7_unknown | FileCheck %s --check-prefix=UNKNOWN_A7
 
+
+# RUN: llvm-mc -filetype=obj -triple=riscv64  x3_reg_usage_unknown.s -o x3_reg_usage_unknown.o
+# RUN: llvm-mc -filetype=obj -triple=riscv64  x3_reg_usage_gp.s -o x3_reg_usage_gp.o
+# RUN: llvm-mc -filetype=obj -triple=riscv64  x3_reg_usage_scs.s -o x3_reg_usage_scs.o
+# RUN: llvm-mc -filetype=obj -triple=riscv64  x3_reg_usage_tmp.s -o x3_reg_usage_tmp.o
+
+# RUN: not ld.lld x3_reg_usage_scs.o x3_reg_usage_gp.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=X3_REG_SCS_GP --implicit-check-not=error:
+# X3_REG_SCS_GP: error: x3_reg_usage_scs.o:(.riscv.attributes) has x3_reg_usage=2 but x3_reg_usage_gp.o:(.riscv.attributes) has x3_reg_usage=1
+
+# RUN: not ld.lld x3_reg_usage_scs.o x3_reg_usage_tmp.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=X3_REG_SCS_TMP --implicit-check-not=error:
+# X3_REG_SCS_TMP: error: x3_reg_usage_scs.o:(.riscv.attributes) has x3_reg_usage=2 but x3_reg_usage_tmp.o:(.riscv.attributes) has x3_reg_usage=3
+
+
+# RUN: ld.lld x3_reg_usage_scs.o x3_reg_usage_unknown.o -o x3_reg_usage_scs_unknown
+# RUN: llvm-readobj -A x3_reg_usage_scs_unknown | FileCheck %s --check-prefix=X3_REG_SCS_UKNOWN
+
+
 ## The deprecated priv_spec is not handled as GNU ld does.
 ## Differing priv_spec attributes lead to an absent attribute.
 # RUN: llvm-mc -filetype=obj -triple=riscv64 diff_priv_spec.s -o diff_priv_spec.o
@@ -412,6 +429,40 @@
 # A6S_A7:   }
 # A6S_A7: }
 
+#--- x3_reg_usage_unknown.s
+.attribute x3_reg_usage, 0
+
+#--- x3_reg_usage_gp.s
+.attribute x3_reg_usage, 1
+
+#--- x3_reg_usage_scs.s
+.attribute x3_reg_usage, 2
+
+#--- x3_reg_usage_tmp.s
+.attribute x3_reg_usage, 3
+
+
+# X3_REG_SCS_UKNOWN: BuildAttributes {
+# X3_REG_SCS_UKNOWN:   FormatVersion: 0x41
+# X3_REG_SCS_UKNOWN:   Section 1 {
+# X3_REG_SCS_UKNOWN:     SectionLength: 17
+# X3_REG_SCS_UKNOWN:     Vendor: riscv
+# X3_REG_SCS_UKNOWN:     Tag: Tag_File (0x1)
+# X3_REG_SCS_UKNOWN:     Size: 7
+# X3_REG_SCS_UKNOWN:     FileAttributes {
+# X3_REG_SCS_UKNOWN:       Attribute {
+# X3_REG_SCS_UKNOWN:         Tag: 16
+# X3_REG_SCS_UKNOWN:         Value: 2
+# X3_REG_SCS_UKNOWN:         TagName: x3_reg_usage
+# X3_REG_SCS_UKNOWN:         Description: X3 reg usage is 2
+# X3_REG_SCS_UKNOWN:       }
+# X3_REG_SCS_UKNOWN:     }
+# X3_REG_SCS_UKNOWN:   }
+# X3_REG_SCS_UKNOWN: }
+
+
+
+
 #--- unknown13.s
 .attribute 13, "0"
 #--- unknown13a.s
diff --git a/llvm/include/llvm/Support/RISCVAttributeParser.h b/llvm/include/llvm/Support/RISCVAttributeParser.h
index 9f295504de959e..9e7d9149111ad8 100644
--- a/llvm/include/llvm/Support/RISCVAttributeParser.h
+++ b/llvm/include/llvm/Support/RISCVAttributeParser.h
@@ -25,6 +25,7 @@ class RISCVAttributeParser : public ELFAttributeParser {
   Error unalignedAccess(unsigned tag);
   Error stackAlign(unsigned tag);
   Error atomicAbi(unsigned tag);
+  Error x3RegUsage(unsigned tag);
 
 public:
   RISCVAttributeParser(ScopedPrinter *sw)
diff --git a/llvm/include/llvm/Support/RISCVAttributes.h b/llvm/include/llvm/Support/RISCVAttributes.h
index 5def890a727355..dcc1436a6c9fc5 100644
--- a/llvm/include/llvm/Support/RISCVAttributes.h
+++ b/llvm/include/llvm/Support/RISCVAttributes.h
@@ -33,6 +33,7 @@ enum AttrType : unsigned {
   PRIV_SPEC_MINOR = 10,
   PRIV_SPEC_REVISION = 12,
   ATOMIC_ABI = 14,
+  X3_REG_USAGE=16,
 };
 
 namespace RISCVAtomicAbiTag {
@@ -47,6 +48,15 @@ enum AtomicABI : unsigned {
 };
 } // namespace RISCVAtomicAbiTag
 
+namespace RISCVX3RegUse {
+enum X3RegUsage : unsigned {
+  UNKNOWN = 0,
+  GP = 0,
+  SCS = 0,
+  TMP = 0,
+};
+} // namespace RISCVX3RegUse
+
 enum { NOT_ALLOWED = 0, ALLOWED = 1 };
 
 } // namespace RISCVAttrs
diff --git a/llvm/lib/Support/RISCVAttributeParser.cpp b/llvm/lib/Support/RISCVAttributeParser.cpp
index b9515134181edb..7b527ad7f5c588 100644
--- a/llvm/lib/Support/RISCVAttributeParser.cpp
+++ b/llvm/lib/Support/RISCVAttributeParser.cpp
@@ -54,6 +54,13 @@ Error RISCVAttributeParser::atomicAbi(unsigned Tag) {
   return Error::success();
 }
 
+Error RISCVAttributeParser::x3RegUsage(unsigned Tag) {
+  uint64_t Value = de.getULEB128(cursor);
+  std::string Description = "X3 reg usage is " + utostr(Value);
+  printAttribute(Tag, Value, Description);
+  return Error::success();
+}
+
 Error RISCVAttributeParser::unalignedAccess(unsigned tag) {
   static const char *strings[] = {"No unaligned access", "Unaligned access"};
   return parseStringAttribute("Unaligned_access", tag, ArrayRef(strings));
diff --git a/llvm/lib/Support/RISCVAttributes.cpp b/llvm/lib/Support/RISCVAttributes.cpp
index dc70d65acba063..51104263e63248 100644
--- a/llvm/lib/Support/RISCVAttributes.cpp
+++ b/llvm/lib/Support/RISCVAttributes.cpp
@@ -19,6 +19,7 @@ static constexpr TagNameItem tagData[] = {
     {PRIV_SPEC_MINOR, "Tag_priv_spec_minor"},
     {PRIV_SPEC_REVISION, "Tag_priv_spec_revision"},
     {ATOMIC_ABI, "Tag_atomic_abi"},
+    {X3_REG_USAGE, "Tag_x3_reg_usage"},
 };
 
 constexpr TagNameMap RISCVAttributeTags{tagData};
diff --git a/llvm/test/CodeGen/RISCV/attributes.ll b/llvm/test/CodeGen/RISCV/attributes.ll
index 95bce2ae8a071a..313d1ad44656ac 100644
--- a/llvm/test/CodeGen/RISCV/attributes.ll
+++ b/llvm/test/CodeGen/RISCV/attributes.ll
@@ -520,3 +520,8 @@ define i8 @atomic_load_i8_seq_cst(ptr %a) nounwind {
 ; A6S: .attribute 14, 2
 ; A6C: .attribute 14, 1
 }
+
+define void @f1() shadowcallstack {
+  ret void
+}
+
diff --git a/llvm/test/MC/RISCV/attribute.s b/llvm/test/MC/RISCV/attribute.s
index 0a9d86da55261c..a1e8261d464af2 100644
--- a/llvm/test/MC/RISCV/attribute.s
+++ b/llvm/test/MC/RISCV/attribute.s
@@ -24,6 +24,9 @@
 
 .attribute priv_spec_revision, 0
 # CHECK: attribute      12, 0
+
 .attribute atomic_abi, 0
 # CHECK: attribute      14, 0
 
+.attribute x3_reg_usage, 0
+# CHECK: attribute      16, 0
diff --git a/llvm/test/MC/RISCV/invalid-attribute.s b/llvm/test/MC/RISCV/invalid-attribute.s
index 2ebf7ddc9aff85..5e317ef9e19484 100644
--- a/llvm/test/MC/RISCV/invalid-attribute.s
+++ b/llvm/test/MC/RISCV/invalid-attribute.s
@@ -36,3 +36,6 @@
 
 .attribute atomic_abi, "16"
 # CHECK: [[@LINE-1]]:24: error: expected numeric constant
+
+.attribute x3_reg_usage, "16"
+# CHECK: [[@LINE-1]]:26: error: expected numeric constant

``````````

</details>


https://github.com/llvm/llvm-project/pull/84598


More information about the llvm-branch-commits mailing list