Skip to content

Conversation

@leidian977
Copy link

@leidian977 leidian977 commented Dec 6, 2025

Summary

This PR adds Propeller optimization framework support to the RISC-V backend.

Motivation

Currently, LLVM's Propeller is only supported on x86 and aarch64. This limits profile-guided
optimizations for RISC-V targets. This patch extends Propeller support to RISC-V.

@github-actions
Copy link

github-actions bot commented Dec 6, 2025

Thank you for submitting a Pull Request (PR) to the LLVM Project!

This PR will be automatically labeled and the relevant teams will be notified.

If you wish to, you can add reviewers by using the "Reviewers" section on this page.

If this is not working for you, it is probably because you do not have write permissions for the repository. In which case you can instead tag reviewers by name in a comment by using @ followed by their GitHub username.

If you have received no comments on your PR for a week, you can request a review by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate is once a week. Please remember that you are asking for valuable time from other developers.

If you have further questions, they may be answered by the LLVM GitHub User Guide.

You can also ask questions in a comment on this PR, on the LLVM Discord or on the forums.

@llvmbot llvmbot added backend:RISC-V clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' labels Dec 6, 2025
@llvmbot
Copy link
Member

llvmbot commented Dec 6, 2025

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

Author: None (leidian977)

Changes

Summary

This PR adds Propeller optimization framework support to the RISC-V backend.

Motivation

Currently, LLVM's Propeller is only supported on x86. This limits profile-guided
optimizations for RISC-V targets. This patch extends Propeller support to RISC-V.


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

3 Files Affected:

  • (modified) clang/lib/Driver/ToolChains/Clang.cpp (+7)
  • (modified) llvm/lib/Target/RISCV/RISCVInstrInfo.cpp (+9)
  • (modified) llvm/lib/Target/RISCV/RISCVInstrInfo.h (+3)
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 0380568412e62..d6b93777b8dd1 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -6128,6 +6128,13 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
             << A->getAsString(Args) << A->getValue();
       else
         A->render(Args, CmdArgs);
+    } else if (Triple.isRISCV() && Triple.isOSBinFormatELF()) {
+      // Add RISC-V support for basic block sections
+      if (Val != "labels" && Val != "none" && !Val.starts_with("list="))
+        D.Diag(diag::err_drv_invalid_value)
+            << A->getAsString(Args) << A->getValue();
+      else
+        A->render(Args, CmdArgs);
     } else if (Triple.isNVPTX()) {
       // Do not pass the option to the GPU compilation. We still want it enabled
       // for the host-side compilation, so seeing it here is not an error.
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
index 9fb7ac0573824..269a3ca539635 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -89,6 +89,15 @@ RISCVInstrInfo::RISCVInstrInfo(const RISCVSubtarget &STI)
 #define GET_INSTRINFO_HELPERS
 #include "RISCVGenInstrInfo.inc"
 
+void RISCVInstrInfo::insertNoop(MachineBasicBlock &MBB,
+                                MachineBasicBlock::iterator MI) const {
+  DebugLoc DL;
+  BuildMI(MBB, MI, DL, get(RISCV::ADDI))
+      .addReg(RISCV::X0)
+      .addReg(RISCV::X0)
+      .addImm(0);
+}
+
 MCInst RISCVInstrInfo::getNop() const {
   if (STI.hasStdExtZca())
     return MCInstBuilder(RISCV::C_NOP);
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.h b/llvm/lib/Target/RISCV/RISCVInstrInfo.h
index 0ffe015b9fac8..bf12c1900be25 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.h
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.h
@@ -86,6 +86,9 @@ class RISCVInstrInfo : public RISCVGenInstrInfo {
 
   const RISCVRegisterInfo &getRegisterInfo() const { return RegInfo; }
 
+  void insertNoop(MachineBasicBlock &MBB,
+                  MachineBasicBlock::iterator MI) const override;
+
   MCInst getNop() const override;
 
   Register isLoadFromStackSlot(const MachineInstr &MI,

@llvmbot
Copy link
Member

llvmbot commented Dec 6, 2025

@llvm/pr-subscribers-clang-driver

Author: None (leidian977)

Changes

Summary

This PR adds Propeller optimization framework support to the RISC-V backend.

Motivation

Currently, LLVM's Propeller is only supported on x86. This limits profile-guided
optimizations for RISC-V targets. This patch extends Propeller support to RISC-V.


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

3 Files Affected:

  • (modified) clang/lib/Driver/ToolChains/Clang.cpp (+7)
  • (modified) llvm/lib/Target/RISCV/RISCVInstrInfo.cpp (+9)
  • (modified) llvm/lib/Target/RISCV/RISCVInstrInfo.h (+3)
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 0380568412e62..d6b93777b8dd1 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -6128,6 +6128,13 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
             << A->getAsString(Args) << A->getValue();
       else
         A->render(Args, CmdArgs);
+    } else if (Triple.isRISCV() && Triple.isOSBinFormatELF()) {
+      // Add RISC-V support for basic block sections
+      if (Val != "labels" && Val != "none" && !Val.starts_with("list="))
+        D.Diag(diag::err_drv_invalid_value)
+            << A->getAsString(Args) << A->getValue();
+      else
+        A->render(Args, CmdArgs);
     } else if (Triple.isNVPTX()) {
       // Do not pass the option to the GPU compilation. We still want it enabled
       // for the host-side compilation, so seeing it here is not an error.
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
index 9fb7ac0573824..269a3ca539635 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -89,6 +89,15 @@ RISCVInstrInfo::RISCVInstrInfo(const RISCVSubtarget &STI)
 #define GET_INSTRINFO_HELPERS
 #include "RISCVGenInstrInfo.inc"
 
+void RISCVInstrInfo::insertNoop(MachineBasicBlock &MBB,
+                                MachineBasicBlock::iterator MI) const {
+  DebugLoc DL;
+  BuildMI(MBB, MI, DL, get(RISCV::ADDI))
+      .addReg(RISCV::X0)
+      .addReg(RISCV::X0)
+      .addImm(0);
+}
+
 MCInst RISCVInstrInfo::getNop() const {
   if (STI.hasStdExtZca())
     return MCInstBuilder(RISCV::C_NOP);
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.h b/llvm/lib/Target/RISCV/RISCVInstrInfo.h
index 0ffe015b9fac8..bf12c1900be25 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.h
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.h
@@ -86,6 +86,9 @@ class RISCVInstrInfo : public RISCVGenInstrInfo {
 
   const RISCVRegisterInfo &getRegisterInfo() const { return RegInfo; }
 
+  void insertNoop(MachineBasicBlock &MBB,
+                  MachineBasicBlock::iterator MI) const override;
+
   MCInst getNop() const override;
 
   Register isLoadFromStackSlot(const MachineInstr &MI,

Copy link
Contributor

@wangpc-pp wangpc-pp left a comment

Choose a reason for hiding this comment

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

Thanks! We are interested in this work!

There are some suggestions:

  1. Please add some tests for these driver changes.
  2. Can you describe what we are missing for the support of Propeller in the middle/back ends? For example, I don't know the relationship between Propeller and insertNoop.
  3. Can you show the current status and the state after your changes? Have you tried it on real hardware and do we need anything else to make Propeller work?

@leidian977
Copy link
Author

Thanks! We are interested in this work!

There are some suggestions:

1. Please add some tests for these driver changes.

2. Can you describe what we are missing for the support of Propeller in the middle/back ends? For example, I don't know the relationship between Propeller and `insertNoop`.

3. Can you show the current status and the state after your changes? Have you tried it on real hardware and do we need anything else to make Propeller work?

1.I've added the tests. Please take a look.

2.The Basic Block Sections feature requires inserting NOP instructions in certain cases to avoid zero-offset exception landing pads.When I compile 510.parest_r from SPEC CPU2017 using the propeller feature, it triggers:

Target didn't implement insertNoop!
UNREACHABLE executed at llvm/lib/CodeGen/TargetInstrInfo.cpp:84!
......
Running pass 'Function Pass Manager' on module 'ld-temp.o'.
Running pass 'Basic Block Sections Analysis' on function '@_GLOBAL__sub_I_Compute.C' #0 0x00007ed74bafaefc llvm::sys::PrintStackTrace(llvm::raw_ostream&, int)
......
ErrorHandling.cpp:242:55 #11 0x00007ed7449f858c llvm::TargetInstrInfo::insertNoops(llvm::MachineBasicBlock&, llvm::MachineInstrBundleIterator<llvm::MachineInstr, false>, unsigned int) const llvm/lib/CodeGen/TargetInstrInfo.cpp:91:60 #12 0x0000
  1. Successfully implemented and tested the Propeller feature on RISC-V Clang

Copy link
Contributor

@wangpc-pp wangpc-pp left a comment

Choose a reason for hiding this comment

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

LGTM. Thanks!

Copy link
Collaborator

@topperc topperc left a comment

Choose a reason for hiding this comment

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

LGTM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend:RISC-V clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl'

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants