Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[llvm][lld][RISCV] Support x3_reg_usage #84598

Open
wants to merge 35 commits into
base: main
Choose a base branch
from

Conversation

ilovepi
Copy link
Contributor

@ilovepi ilovepi commented Mar 9, 2024

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.

@llvmbot
Copy link
Collaborator

llvmbot commented Mar 9, 2024

@llvm/pr-subscribers-backend-risc-v
@llvm/pr-subscribers-lld-elf

@llvm/pr-subscribers-lld

Author: Paul Kirth (ilovepi)

Changes

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 --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

@llvmbot
Copy link
Collaborator

llvmbot commented Mar 9, 2024

@llvm/pr-subscribers-mc

Author: Paul Kirth (ilovepi)

Changes

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 --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

Created using spr 1.3.4

[skip ci]
Created using spr 1.3.4
@ilovepi ilovepi requested a review from jrtc27 March 9, 2024 07:12
Created using spr 1.3.4

[skip ci]
Created using spr 1.3.4
Created using spr 1.3.4

[skip ci]
Created using spr 1.3.4
Created using spr 1.3.4

[skip ci]
Created using spr 1.3.4
if (newTag == X3RegUsage::UNKNOWN)
return;
if (oldTag == X3RegUsage::UNKNOWN) {
intAttr[attr] = newTag;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use the iterator from try_emplace instead of a second map lookup?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, I think that will work. Let me give that a try.

@@ -24,6 +24,9 @@

.attribute priv_spec_revision, 0
# CHECK: attribute 12, 0

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This blank should be added in Atomic ABI PR I think.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you. There is a good chance that is the case.

@@ -520,3 +520,8 @@ define i8 @atomic_load_i8_seq_cst(ptr %a) nounwind {
; A6S: .attribute 14, 2
; A6C: .attribute 14, 1
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No CHECKs for this test or I miss something here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I'm a little stuck on how to infer the attribute. This function will get a test once I have that figured out.

namespace RISCVX3RegUse {
enum X3RegUsage : unsigned {
UNKNOWN = 0,
GP = 0,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy paste mistakes? Why all 0s?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ugh, you are correct. I haven't tested this properly yet, since I'm not 100% sure what the correct way to add the attribute will be. But I'll up date these to have the proper values from the psABI.

@ilovepi
Copy link
Contributor Author

ilovepi commented Mar 11, 2024

I forgot to mention that I'm still trying to figure out how to add the attribute. I know mechanically how, but AFAIK there isn't a target feature or anything we set when enabling SCS(except for Zcfiscs), so if there is an obvious way, a pointer would be welcome. I think that's something we need to set in STI, so I'm looking into changes to allow that.

Created using spr 1.3.4

[skip ci]
Created using spr 1.3.4
Created using spr 1.3.4

[skip ci]
Created using spr 1.3.4
@@ -50,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);
Copy link
Member

@MaskRay MaskRay Mar 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

printAttribute(..., ("..." + Twine(Value)).str())

.attribute x3_reg_usage, 3

# X3_REG_SCS_UKNOWN: BuildAttributes {
# X3_REG_SCS_UKNOWN: FormatVersion: 0x41
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add -NEXT: whenever appropriate

return;
}
if (oldTag != newTag) {
errorOrWarn(toString(oldSection) + " has x3_reg_usage=" + Twine(oldTag) +
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We seem to use errors for parsing errors. This is probably a warning.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. I've changed it to an error, but it's now inconsistent w/ STACK_ALIGN a few lines up. Should we change that too?

@ilovepi
Copy link
Contributor Author

ilovepi commented Mar 15, 2024

I've tried to use SubtargetFeatures to model the behavior here, but I don't really love the approach. It feels to me like I've chosen the wrong construct, but I'm not sure what that would be. There are obviously still some changes that would be required in the Clang driver to land this(at least for the SCS and GP-relax cases), but I'd rather wait until the mechanism is agreed upon before doing that.

Created using spr 1.3.4

[skip ci]
Created using spr 1.3.4
Created using spr 1.3.4
Created using spr 1.3.4
Created using spr 1.3.4

[skip ci]
Created using spr 1.3.4
Created using spr 1.3.4

[skip ci]
Created using spr 1.3.4
Created using spr 1.3.4

[skip ci]
Created using spr 1.3.4
Created using spr 1.3.4

[skip ci]
Created using spr 1.3.4
Created using spr 1.3.4

[skip ci]
Created using spr 1.3.4
Created using spr 1.3.4

[skip ci]
Created using spr 1.3.4
Created using spr 1.3.4

[skip ci]
Created using spr 1.3.4
@ilovepi ilovepi changed the base branch from users/ilovepi/spr/main.llvmlldriscv-support-x3_reg_usage to main April 25, 2024 23:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants