[clang] [llvm] [RISC-V]Implement -m{,no}fence-tso (PR #151638)

Liao Chunyu via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 1 01:19:48 PDT 2025


https://github.com/ChunyuLiao updated https://github.com/llvm/llvm-project/pull/151638

>From 1714ccb73767e830bda454ea9e94e807f74d3f47 Mon Sep 17 00:00:00 2001
From: Liao Chunyu <chunyu at iscas.ac.cn>
Date: Thu, 31 Jul 2025 21:25:21 -0400
Subject: [PATCH 1/2] [RISC-V]Implement -m{,no}fence-tso

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?
---
 clang/include/clang/Driver/Options.td       |  7 +++++++
 clang/lib/Driver/ToolChains/Arch/RISCV.cpp  |  7 +++++++
 clang/test/Driver/riscv-features.c          |  8 ++++++++
 llvm/lib/Target/RISCV/RISCVFeatures.td      |  3 +++
 llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 10 ++++++++++
 llvm/test/CodeGen/RISCV/atomic-fence.ll     | 20 ++++++++++++++++++++
 llvm/test/CodeGen/RISCV/features-info.ll    |  1 +
 7 files changed, 56 insertions(+)

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.

>From 3544707be65daf8669828a0403167d9baf4a8182 Mon Sep 17 00:00:00 2001
From: Liao Chunyu <chunyu at iscas.ac.cn>
Date: Fri, 1 Aug 2025 04:16:48 -0400
Subject: [PATCH 2/2] making the default case command line shorter, not add
 -no-fence-tso

---
 clang/lib/Driver/ToolChains/Arch/RISCV.cpp | 5 +----
 clang/test/Driver/riscv-features.c         | 4 ++--
 2 files changed, 3 insertions(+), 6 deletions(-)

diff --git a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
index 6d63555f8e980..e7eb6eccc698d 100644
--- a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
+++ b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
@@ -143,11 +143,8 @@ void riscv::getRISCVTargetFeatures(const Driver &D, const llvm::Triple &Triple,
   }
 
   // -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 {
+  if (Args.hasFlag(options::OPT_mno_fence_tso, options::OPT_mfence_tso, false))
     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
diff --git a/clang/test/Driver/riscv-features.c b/clang/test/Driver/riscv-features.c
index ef003fddb692b..b71736fa1464c 100644
--- a/clang/test/Driver/riscv-features.c
+++ b/clang/test/Driver/riscv-features.c
@@ -32,9 +32,9 @@
 // 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"
+// FENCE-TSO-NOT: "-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"
 // 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



More information about the llvm-commits mailing list