Skip to content

[RISC-V]Implement -m{,no}fence-tso #151638

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

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

Conversation

ChunyuLiao
Copy link
Member

@ChunyuLiao ChunyuLiao commented Aug 1, 2025

Some processors from T-Head don't implement the fence.tso instruction natively and instead trap to firmware. So just add an option to disable emitting it.

The requirement comes from Debian, link: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1070959

Some processors from T-Head don't implement the `fence.tso` instruction
natively and instead trap to firmware. So just add an option to disable emitting it.

The requirement comes from Debian, link: https://bugs.debian.org/cgi-bin/bugreport.cgi?
@llvmbot llvmbot added clang Clang issues not falling into any other category backend:RISC-V clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' labels Aug 1, 2025
@llvmbot
Copy link
Member

llvmbot commented Aug 1, 2025

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

@llvm/pr-subscribers-clang-driver

Author: Liao Chunyu (ChunyuLiao)

Changes

Some processors from T-Head don't implement the fence.tso instruction natively and instead trap to firmware. So just add an option to disable emitting it.

The requirement comes from Debian, link: https://bugs.debian.org/cgi-bin/bugreport.cgi?


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

7 Files Affected:

  • (modified) clang/include/clang/Driver/Options.td (+7)
  • (modified) clang/lib/Driver/ToolChains/Arch/RISCV.cpp (+7)
  • (modified) clang/test/Driver/riscv-features.c (+8)
  • (modified) llvm/lib/Target/RISCV/RISCVFeatures.td (+3)
  • (modified) llvm/lib/Target/RISCV/RISCVISelLowering.cpp (+10)
  • (modified) llvm/test/CodeGen/RISCV/atomic-fence.ll (+20)
  • (modified) llvm/test/CodeGen/RISCV/features-info.ll (+1)
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 3c04aeb5af59c..2ded1b9a4f51c 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -5120,6 +5120,13 @@ def msave_restore : Flag<["-"], "msave-restore">, Group<m_riscv_Features_Group>,
   HelpText<"Enable using library calls for save and restore">;
 def mno_save_restore : Flag<["-"], "mno-save-restore">, Group<m_riscv_Features_Group>,
   HelpText<"Disable using library calls for save and restore">;
+def mfence_tso : Flag<["-"], "mfence-tso">,
+                 Group<m_Group>,
+                 HelpText<"Enable using fence-tso">;
+def mno_fence_tso : Flag<["-"], "mno-fence-tso">,
+                    Group<m_Group>,
+                    HelpText<"Disable using fence-tso">;
+
 } // let Flags = [TargetSpecific]
 let Flags = [TargetSpecific] in {
 def menable_experimental_extensions : Flag<["-"], "menable-experimental-extensions">, Group<m_Group>,
diff --git a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
index baa2c8c0bcfb2..6d63555f8e980 100644
--- a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
+++ b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
@@ -142,6 +142,13 @@ void riscv::getRISCVTargetFeatures(const Driver &D, const llvm::Triple &Triple,
     Features.push_back("-relax");
   }
 
+  // -mfence-tso is default, unless -mno-fence-tso is specified.
+  if (Args.hasFlag(options::OPT_mfence_tso, options::OPT_mno_fence_tso, true)) {
+    Features.push_back("-no-fence-tso");
+  } else {
+    Features.push_back("+no-fence-tso");
+  }
+
   // If -mstrict-align, -mno-strict-align, -mscalar-strict-align, or
   // -mno-scalar-strict-align is passed, use it. Otherwise, the
   // unaligned-scalar-mem is enabled if the CPU supports it or the target is
diff --git a/clang/test/Driver/riscv-features.c b/clang/test/Driver/riscv-features.c
index 80dec2c71f985..ef003fddb692b 100644
--- a/clang/test/Driver/riscv-features.c
+++ b/clang/test/Driver/riscv-features.c
@@ -29,6 +29,14 @@
 // DEFAULT-NOT: "-target-feature" "-save-restore"
 // DEFAULT-NOT: "-target-feature" "+save-restore"
 
+// RUN: %clang --target=riscv32-unknown-elf -### %s -mfence-tso 2>&1 | FileCheck %s -check-prefix=FENCE-TSO
+// RUN: %clang --target=riscv32-unknown-elf -### %s -mno-fence-tso 2>&1 | FileCheck %s -check-prefix=NO-FENCE-TSO
+
+// FENCE-TSO: "-target-feature" "-no-fence-tso"
+// NO-FENCE-TSO: "-target-feature" "+no-fence-tso"
+// DEFAULT: "-target-feature" "-no-fence-tso"
+// DEFAULT-NOT: "-target-feature" "+no-fence-tso"
+
 // RUN: %clang --target=riscv32-unknown-elf -### %s -mno-strict-align 2>&1 | FileCheck %s -check-prefixes=FAST-SCALAR-UNALIGNED-ACCESS,FAST-VECTOR-UNALIGNED-ACCESS
 // RUN: %clang --target=riscv32-unknown-elf -### %s -mstrict-align 2>&1 | FileCheck %s -check-prefixes=NO-FAST-SCALAR-UNALIGNED-ACCESS,NO-FAST-VECTOR-UNALIGNED-ACCESS
 // RUN: %clang --target=riscv32-unknown-elf -### %s -mno-scalar-strict-align 2>&1 | FileCheck %s -check-prefix=FAST-SCALAR-UNALIGNED-ACCESS
diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td
index 171940e149815..abcf6cd5f8699 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -1678,6 +1678,9 @@ foreach i = {1-31} in
 def FeatureSaveRestore : SubtargetFeature<"save-restore", "EnableSaveRestore",
                                           "true", "Enable save/restore.">;
 
+def FeatureNoFenceTso : SubtargetFeature<"no-fence-tso", "EnableFenceTso",
+                                         "false", "Don't use fence.tso.">;
+
 def FeatureNoTrailingSeqCstFence : SubtargetFeature<"no-trailing-seq-cst-fence",
                                           "EnableTrailingSeqCstFence",
                                           "false",
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index c0ada51ef4403..bdaa85ff4076e 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -6688,6 +6688,16 @@ static SDValue LowerATOMIC_FENCE(SDValue Op, SelectionDAG &DAG,
     // MEMBARRIER is a compiler barrier; it codegens to a no-op.
     return DAG.getNode(ISD::MEMBARRIER, dl, MVT::Other, Op.getOperand(0));
 
+  if (!Subtarget.enableFenceTso() &&
+      FenceOrdering == AtomicOrdering::AcquireRelease) {
+    const TargetLowering &TLI = DAG.getTargetLoweringInfo();
+    SDValue Op1 =
+        DAG.getTargetConstant((unsigned)AtomicOrdering::SequentiallyConsistent,
+                              dl, TLI.getFenceOperandTy(DAG.getDataLayout()));
+    return DAG.getNode(ISD::ATOMIC_FENCE, dl, MVT::Other, Op.getOperand(0), Op1,
+                       Op.getOperand(2));
+  }
+
   return Op;
 }
 
diff --git a/llvm/test/CodeGen/RISCV/atomic-fence.ll b/llvm/test/CodeGen/RISCV/atomic-fence.ll
index 7103345ce7bc2..74312c6396105 100644
--- a/llvm/test/CodeGen/RISCV/atomic-fence.ll
+++ b/llvm/test/CodeGen/RISCV/atomic-fence.ll
@@ -1,6 +1,8 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
 ; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
 ; RUN:   | FileCheck --check-prefixes=CHECK,WMO %s
+; RUN: llc -mtriple=riscv32 -mattr=+no-fence-tso -verify-machineinstrs < %s \
+; RUN:   | FileCheck --check-prefixes=CHECK,NTSO %s
 ; RUN: llc -mtriple=riscv32 -mattr=+a -verify-machineinstrs < %s \
 ; RUN:   | FileCheck --check-prefixes=CHECK,WMO %s
 ; RUN: llc -mtriple=riscv32 -mattr=+a,+ztso -verify-machineinstrs < %s \
@@ -11,6 +13,9 @@
 ; RUN:   | FileCheck --check-prefixes=CHECK,WMO %s
 ; RUN: llc -mtriple=riscv64 -mattr=+a,+ztso -verify-machineinstrs < %s \
 ; RUN:   | FileCheck --check-prefixes=CHECK,TSO %s
+; RUN: llc -mtriple=riscv64 -mattr=+no-fence-tso -verify-machineinstrs < %s \
+; RUN:   | FileCheck --check-prefixes=CHECK,NTSO %s
+
 
 define void @fence_acquire() nounwind {
 ; WMO-LABEL: fence_acquire:
@@ -18,6 +23,11 @@ define void @fence_acquire() nounwind {
 ; WMO-NEXT:    fence r, rw
 ; WMO-NEXT:    ret
 ;
+; NTSO-LABEL: fence_acquire:
+; NTSO:       # %bb.0:
+; NTSO-NEXT:    fence r, rw
+; NTSO-NEXT:    ret
+;
 ; TSO-LABEL: fence_acquire:
 ; TSO:       # %bb.0:
 ; TSO-NEXT:    #MEMBARRIER
@@ -32,6 +42,11 @@ define void @fence_release() nounwind {
 ; WMO-NEXT:    fence rw, w
 ; WMO-NEXT:    ret
 ;
+; NTSO-LABEL: fence_release:
+; NTSO:       # %bb.0:
+; NTSO-NEXT:    fence rw, w
+; NTSO-NEXT:    ret
+;
 ; TSO-LABEL: fence_release:
 ; TSO:       # %bb.0:
 ; TSO-NEXT:    #MEMBARRIER
@@ -46,6 +61,11 @@ define void @fence_acq_rel() nounwind {
 ; WMO-NEXT:    fence.tso
 ; WMO-NEXT:    ret
 ;
+; NTSO-LABEL: fence_acq_rel:
+; NTSO:       # %bb.0:
+; NTSO-NEXT:    fence rw, rw
+; NTSO-NEXT:    ret
+;
 ; TSO-LABEL: fence_acq_rel:
 ; TSO:       # %bb.0:
 ; TSO-NEXT:    #MEMBARRIER
diff --git a/llvm/test/CodeGen/RISCV/features-info.ll b/llvm/test/CodeGen/RISCV/features-info.ll
index b94665b718ae7..5d1be56382d46 100644
--- a/llvm/test/CodeGen/RISCV/features-info.ll
+++ b/llvm/test/CodeGen/RISCV/features-info.ll
@@ -61,6 +61,7 @@
 ; CHECK-NEXT:   m                                - 'M' (Integer Multiplication and Division).
 ; CHECK-NEXT:   mips-p8700                       - MIPS p8700 processor.
 ; CHECK-NEXT:   no-default-unroll                - Disable default unroll preference..
+; CHECK-NEXT:   no-fence-tso                     - Don't use fence.tso..
 ; CHECK-NEXT:   no-sink-splat-operands           - Disable sink splat operands to enable .vx, .vf,.wx, and .wf instructions.
 ; CHECK-NEXT:   no-trailing-seq-cst-fence        - Disable trailing fence for seq-cst store..
 ; CHECK-NEXT:   optimized-nf2-segment-load-store - vlseg2eN.v and vsseg2eN.v are implemented as a wide memory op and shuffle.

@topperc
Copy link
Collaborator

topperc commented Aug 1, 2025

The link is the description is incomplete

@ChunyuLiao
Copy link
Member Author

The link is the description is incomplete

Thanks. Updated the link : https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1070959

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' clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants