[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