Skip to content

[RISCV] Select the capability ABI by default when the Y extension is enabled - #213411

Merged
arichardson merged 10 commits into
mainfrom
users/arichardson/spr/riscv-select-the-capability-abi-by-default-when-the-y-extension-is-enabled
Sep 15, 2026
Merged

arichardson merged 10 commits into
mainfrom
users/arichardson/spr/riscv-select-the-capability-abi-by-default-when-the-y-extension-is-enabled

Conversation

@arichardson

@arichardson arichardson commented Aug 1, 2026

Copy link
Copy Markdown
Member

computeDefaultABI() previously had no knowledge of the RVY (CHERI) base,
so a target with Y enabled and no explicit -target-abi
would fall back to the plain integer ABI instead of il32pc64(d)/
l64pc128(d).

This adds explicit non-RVY ABIs to two tests since otherwise those would
hit the assertion that the ABI is not supported yet. As the ABI does not
matter for these tests, we can safely use the non-RVY ones.

This change was created with the help of AI tools

Created using spr 1.3.8-beta.1-arichardson

[skip ci]
Created using spr 1.3.8-beta.1-arichardson
@llvmorg-github-actions

Copy link
Copy Markdown

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

Author: Alexander Richardson (arichardson)

Changes

computeDefaultABI() previously had no knowledge of the Y (CHERI)
extension, so a target with Y enabled and no explicit -target-abi
would fall back to the plain integer ABI instead of il32pc64(d)/
l64pc128(d).

This change was created with the help of AI tools


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

5 Files Affected:

  • (modified) llvm/lib/TargetParser/RISCVISAInfo.cpp (+10-7)
  • (modified) llvm/test/CodeGen/RISCV/attributes.ll (+1-1)
  • (modified) llvm/test/CodeGen/RISCV/rvy/rvy-invalid-operands.mir (+2-2)
  • (modified) llvm/unittests/Target/RISCV/RISCVBaseInfoTest.cpp (+25)
  • (modified) llvm/unittests/TargetParser/RISCVISAInfoTest.cpp (+16)
diff --git a/llvm/lib/TargetParser/RISCVISAInfo.cpp b/llvm/lib/TargetParser/RISCVISAInfo.cpp
index 9d4ce85efe187..5ec7d456eb36a 100644
--- a/llvm/lib/TargetParser/RISCVISAInfo.cpp
+++ b/llvm/lib/TargetParser/RISCVISAInfo.cpp
@@ -1082,24 +1082,27 @@ RISCVISAInfo::postProcessAndChecking(std::unique_ptr<RISCVISAInfo> &&ISAInfo) {
 }
 
 StringRef RISCVISAInfo::computeDefaultABI() const {
+  bool HasY = Exts.count("y") != 0;
   if (XLen == 32) {
     if (Exts.count("xcheriot"))
       return "cheriot";
     if (Exts.count("e"))
-      return "ilp32e";
+      return HasY ? "il32pc64e" : "ilp32e";
     if (Exts.count("d"))
-      return "ilp32d";
+      return HasY ? "il32pc64d" : "ilp32d";
     if (Exts.count("f"))
-      return "ilp32f";
-    return "ilp32";
+      return HasY ? "il32pc64f" : "ilp32f";
+    return HasY ? "il32pc64" : "ilp32";
   } else if (XLen == 64) {
+    // There is no l64pc128e ABI, so RV64E still uses the integer ABI even
+    // when the Y extension is enabled.
     if (Exts.count("e"))
       return "lp64e";
     if (Exts.count("d"))
-      return "lp64d";
+      return HasY ? "l64pc128d" : "lp64d";
     if (Exts.count("f"))
-      return "lp64f";
-    return "lp64";
+      return HasY ? "l64pc128f" : "lp64f";
+    return HasY ? "l64pc128" : "lp64";
   }
   llvm_unreachable("Invalid XLEN");
 }
diff --git a/llvm/test/CodeGen/RISCV/attributes.ll b/llvm/test/CodeGen/RISCV/attributes.ll
index e5f1aa0292dd9..a8775d0faa7a8 100644
--- a/llvm/test/CodeGen/RISCV/attributes.ll
+++ b/llvm/test/CodeGen/RISCV/attributes.ll
@@ -323,7 +323,7 @@
 ; RUN: llc -mtriple=riscv64 -mattr=+sdext  %s -o - | FileCheck --check-prefix=RV64SDEXT %s
 ; RUN: llc -mtriple=riscv64 -mattr=+sdtrig  %s -o - | FileCheck --check-prefix=RV64SDTRIG %s
 ; RUN: llc -mtriple=riscv64 -mattr=+experimental-p %s -o - | FileCheck --check-prefix=RV64P %s
-; RUN: llc -mtriple=riscv64 -mattr=+experimental-y %s -o - | FileCheck --check-prefix=RV64Y %s
+; RUN: llc -mtriple=riscv64 -mattr=+experimental-y -target-abi lp64 %s -o - | FileCheck --check-prefix=RV64Y %s
 ; RUN: llc -mtriple=riscv64 -mattr=+experimental-zibi %s -o - | FileCheck --check-prefix=RV64ZIBI %s
 ; RUN: llc -mtriple=riscv64 -mattr=+experimental-zilx %s -o - | FileCheck --check-prefix=RV64ZILX %s
 ; RUN: llc -mtriple=riscv64 -mattr=+experimental-zvqwbdota8i %s -o - | FileCheck --check-prefixes=CHECK,RV64ZVQWBDOTA8I %s
diff --git a/llvm/test/CodeGen/RISCV/rvy/rvy-invalid-operands.mir b/llvm/test/CodeGen/RISCV/rvy/rvy-invalid-operands.mir
index 269ba1f4da870..d5939613b9b65 100644
--- a/llvm/test/CodeGen/RISCV/rvy/rvy-invalid-operands.mir
+++ b/llvm/test/CodeGen/RISCV/rvy/rvy-invalid-operands.mir
@@ -1,6 +1,6 @@
-# RUN: not --crash llc -mtriple=riscv32 -mattr=+experimental-y -run-pass machineverifier %s -o - 2>&1 \
+# RUN: not --crash llc -mtriple=riscv32 -mattr=+experimental-y -target-abi ilp32 -run-pass machineverifier %s -o - 2>&1 \
 # RUN:    | FileCheck %s --check-prefixes=CHECK,CHECK-32 --implicit-check-not="Bad machine code"
-# RUN: not --crash llc -mtriple=riscv64 -mattr=+experimental-y -run-pass machineverifier %s -o - 2>&1 \
+# RUN: not --crash llc -mtriple=riscv64 -mattr=+experimental-y -target-abi lp64 -run-pass machineverifier %s -o - 2>&1 \
 # RUN:    | FileCheck %s --check-prefixes=CHECK,CHECK-64  --implicit-check-not="Bad machine code"
 
 # CHECK:      *** Bad machine code: Invalid immediate ***
diff --git a/llvm/unittests/Target/RISCV/RISCVBaseInfoTest.cpp b/llvm/unittests/Target/RISCV/RISCVBaseInfoTest.cpp
index aaec27e166256..0e368953dcbda 100644
--- a/llvm/unittests/Target/RISCV/RISCVBaseInfoTest.cpp
+++ b/llvm/unittests/Target/RISCV/RISCVBaseInfoTest.cpp
@@ -57,6 +57,31 @@ TEST(ComputeTargetABI, SelectsExpectedABI) {
   EXPECT_EQ(computeTargetABI("riscv64", "+f"), RISCVABI::ABI_LP64F);
   EXPECT_EQ(computeTargetABI("riscv64", "+f,+d"), RISCVABI::ABI_LP64D);
 
+  // With the Y extension enabled and no explicit -target-abi, the capability
+  // ABI is selected by default.
+  EXPECT_EQ(computeTargetABI("riscv32", "+experimental-y"),
+            RISCVABI::ABI_IL32PC64);
+  EXPECT_EQ(computeTargetABI("riscv32", "+experimental-y,+f"),
+            RISCVABI::ABI_IL32PC64F);
+  EXPECT_EQ(computeTargetABI("riscv32", "+experimental-y,+f,+d"),
+            RISCVABI::ABI_IL32PC64D);
+  EXPECT_EQ(computeTargetABI("riscv64", "+experimental-y"),
+            RISCVABI::ABI_L64PC128);
+  EXPECT_EQ(computeTargetABI("riscv64", "+experimental-y,+f"),
+            RISCVABI::ABI_L64PC128F);
+  EXPECT_EQ(computeTargetABI("riscv64", "+experimental-y,+f,+d"),
+            RISCVABI::ABI_L64PC128D);
+
+  // An explicitly requested ABI is unaffected by the Y-based default: even
+  // with Y (and F/D) enabled, asking for the plain integer ABI still gives
+  // the integer ABI rather than the capability one.
+  EXPECT_EQ(
+      computeTargetABI("riscv32", "+experimental-y", /*ABIName=*/"ilp32"),
+      RISCVABI::ABI_ILP32);
+  EXPECT_EQ(computeTargetABI("riscv64", "+experimental-y,+f,+d",
+                              /*ABIName=*/"lp64d"),
+            RISCVABI::ABI_LP64D);
+
   // CHERIoT always selects the cheriot ABI by default.
   EXPECT_EQ(computeTargetABI("riscv32", "+xcheriot"), RISCVABI::ABI_CHERIOT);
 }
diff --git a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
index 04cbe8b9f661d..769f28ed7a3ff 100644
--- a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
+++ b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
@@ -1260,6 +1260,22 @@ TEST(ComputeDefaultABI, SelectsExpectedABI) {
   EXPECT_EQ(GetABIFromFeatures(64, {"+f", "+d"}), "lp64d");
   EXPECT_EQ(GetABIFromFeatures(64, {"+e"}), "lp64e");
 
+  // With the Y extension enabled, the capability ABI is selected by default.
+  // Arch strings can't currently combine 'y' with 'e', or place 'y' anywhere
+  // other than right after the base ISA letter (see RejectsInvalidYPosition),
+  // so use parseFeatures to build the extension sets directly instead.
+  EXPECT_EQ(GetABIFromFeatures(32, {"+experimental-y"}), "il32pc64");
+  EXPECT_EQ(GetABIFromFeatures(32, {"+experimental-y", "+f"}), "il32pc64f");
+  EXPECT_EQ(GetABIFromFeatures(32, {"+experimental-y", "+f", "+d"}),
+            "il32pc64d");
+  EXPECT_EQ(GetABIFromFeatures(32, {"+experimental-y", "+e"}), "il32pc64e");
+  EXPECT_EQ(GetABIFromFeatures(64, {"+experimental-y"}), "l64pc128");
+  EXPECT_EQ(GetABIFromFeatures(64, {"+experimental-y", "+f"}), "l64pc128f");
+  EXPECT_EQ(GetABIFromFeatures(64, {"+experimental-y", "+f", "+d"}),
+            "l64pc128d");
+  // There is no l64pc128e ABI, so RV64E+Y still defaults to the integer ABI.
+  EXPECT_EQ(GetABIFromFeatures(64, {"+experimental-y", "+e"}), "lp64e");
+
   // CHERIoT always selects the cheriot ABI by default.
   EXPECT_EQ(GetABIFromFeatures(32, {"+xcheriot"}), "cheriot");
 }

@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown

✅ With the latest revision this PR passed the C/C++ code formatter.

Created using spr 1.3.8-beta.1-arichardson

[skip ci]
Created using spr 1.3.8-beta.1-arichardson
@arichardson
arichardson requested review from jrtc27 and resistor August 1, 2026 06:16
@arichardson

arichardson commented Aug 1, 2026

Copy link
Copy Markdown
Member Author

Depends on #213410 merged now.

Comment thread llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.cpp Outdated
Comment thread llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.cpp Outdated
Comment thread llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.cpp Outdated
arichardson and others added 4 commits September 11, 2026 13:45
Created using spr 1.3.8-beta.1-arichardson

[skip ci]
Created using spr 1.3.8-beta.1-arichardson
Created using spr 1.3.8-beta.1

[skip ci]
Created using spr 1.3.8-beta.1
@arichardson

Copy link
Copy Markdown
Member Author

Apologies for the delay here, I was out for the past two months and had limited time.

; RUN: llc -mtriple=riscv64 -mattr=+sdtrig %s -o - | FileCheck --check-prefix=RV64SDTRIG %s
; RUN: llc -mtriple=riscv64 -mattr=+experimental-p %s -o - | FileCheck --check-prefix=RV64P %s
; RUN: llc -mtriple=riscv64 -mattr=+experimental-y %s -o - | FileCheck --check-prefix=RV64Y %s
; RUN: llc -mtriple=riscv64 -mattr=+experimental-y -target-abi lp64 %s -o - | FileCheck --check-prefix=RV64Y %s

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This change is needed since we otherwise hit the codegen assertion that l64pc128 ABI is unsuported (which needs quite a few more changes before that can be removed).

@lenary lenary left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM

ryanashita and others added 2 commits September 14, 2026 20:46
Created using spr 1.3.8-beta.1

[skip ci]
Created using spr 1.3.8-beta.1
@arichardson
arichardson changed the base branch from users/arichardson/spr/main.riscv-select-the-capability-abi-by-default-when-the-y-extension-is-enabled to main September 15, 2026 03:47
@arichardson
arichardson merged commit cecd28d into main Sep 15, 2026
6 of 19 checks passed
@arichardson
arichardson deleted the users/arichardson/spr/riscv-select-the-capability-abi-by-default-when-the-y-extension-is-enabled branch September 15, 2026 03:47
llvm-upstreamsync Bot pushed a commit to qualcomm/cpullvm-toolchain that referenced this pull request Sep 15, 2026
…tension is enabled

computeDefaultABI() previously had no knowledge of the RVY (CHERI) base,
so a target with Y enabled and no explicit -target-abi
would fall back to the plain integer ABI instead of il32pc64(d)/
l64pc128(d).

This adds explicit non-RVY ABIs to two tests since otherwise those would
hit the assertion that the ABI is not supported yet. As the ABI does not
matter for these tests, we can safely use the non-RVY ones.

This change was created with the help of AI tools

Reviewed By: lenary

Pull Request: llvm/llvm-project#213411
llvm-sync Bot pushed a commit to arm/arm-toolchain that referenced this pull request Sep 15, 2026
…tension is enabled

computeDefaultABI() previously had no knowledge of the RVY (CHERI) base,
so a target with Y enabled and no explicit -target-abi
would fall back to the plain integer ABI instead of il32pc64(d)/
l64pc128(d).

This adds explicit non-RVY ABIs to two tests since otherwise those would
hit the assertion that the ABI is not supported yet. As the ABI does not
matter for these tests, we can safely use the non-RVY ones.

This change was created with the help of AI tools

Reviewed By: lenary

Pull Request: llvm/llvm-project#213411
anilkund pushed a commit to anilkund/llvm-project that referenced this pull request Sep 16, 2026
…enabled

computeDefaultABI() previously had no knowledge of the RVY (CHERI) base,
so a target with Y enabled and no explicit -target-abi
would fall back to the plain integer ABI instead of il32pc64(d)/
l64pc128(d).

This adds explicit non-RVY ABIs to two tests since otherwise those would
hit the assertion that the ABI is not supported yet. As the ABI does not
matter for these tests, we can safely use the non-RVY ones.

This change was created with the help of AI tools

Reviewed By: lenary

Pull Request: llvm#213411
nekoshirro pushed a commit to nekoshirro/Alchemist-LLVM that referenced this pull request Sep 20, 2026
…enabled

computeDefaultABI() previously had no knowledge of the RVY (CHERI) base,
so a target with Y enabled and no explicit -target-abi
would fall back to the plain integer ABI instead of il32pc64(d)/
l64pc128(d).

This adds explicit non-RVY ABIs to two tests since otherwise those would
hit the assertion that the ABI is not supported yet. As the ABI does not
matter for these tests, we can safely use the non-RVY ones.

This change was created with the help of AI tools

Reviewed By: lenary

Pull Request: llvm/llvm-project#213411
Signed-off-by: Hafidz Muzakky <ais.muzakky@gmail.com>
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.

5 participants