Skip to content

Commit 85071a3

Browse files
authored
[PowerPC] Implement fence builtin (#76495)
1 parent e3acfbc commit 85071a3

File tree

7 files changed

+90
-1
lines changed

7 files changed

+90
-1
lines changed

clang/include/clang/Basic/BuiltinsPPC.def

+4
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,10 @@ BUILTIN(__builtin_ppc_fctiw, "dd", "")
110110
BUILTIN(__builtin_ppc_fctiwz, "dd", "")
111111
BUILTIN(__builtin_ppc_fctudz, "dd", "")
112112
BUILTIN(__builtin_ppc_fctuwz, "dd", "")
113+
114+
// fence builtin prevents all instructions moved across it
115+
BUILTIN(__builtin_ppc_fence, "v", "")
116+
113117
BUILTIN(__builtin_ppc_swdiv_nochk, "ddd", "")
114118
BUILTIN(__builtin_ppc_swdivs_nochk, "fff", "")
115119
BUILTIN(__builtin_ppc_alignx, "vIivC*", "nc")

clang/lib/Basic/Targets/PPC.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@ static void defineXLCompatMacros(MacroBuilder &Builder) {
212212
Builder.defineMacro("__darn_32", "__builtin_darn_32");
213213
Builder.defineMacro("__darn_raw", "__builtin_darn_raw");
214214
Builder.defineMacro("__dcbf", "__builtin_dcbf");
215+
Builder.defineMacro("__fence", "__builtin_ppc_fence");
215216
Builder.defineMacro("__fmadd", "__builtin_fma");
216217
Builder.defineMacro("__fmadds", "__builtin_fmaf");
217218
Builder.defineMacro("__abs", "__builtin_abs");

clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-sync.c

+24
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,18 @@ void test_dcbz() {
194194
__dcbz(c);
195195
}
196196

197+
// CHECK-LABEL: @test_fence(
198+
// CHECK: call void @llvm.ppc.fence()
199+
// CHECK-NEXT: ret void
200+
//
201+
// CHECK-32-LABEL: @test_fence(
202+
// CHECK-32: call void @llvm.ppc.fence()
203+
// CHECK-32-NEXT: ret void
204+
//
205+
void test_fence() {
206+
__fence();
207+
}
208+
197209
// CHECK-LABEL: @test_builtin_ppc_popcntb(
198210
// CHECK: [[TMP0:%.*]] = load i64, ptr @a, align 8
199211
// CHECK-NEXT: [[POPCNTB:%.*]] = call i64 @llvm.ppc.popcntb.i64.i64(i64 [[TMP0]])
@@ -375,3 +387,15 @@ void test_builtin_ppc_dcbtst() {
375387
void test_builtin_ppc_dcbz() {
376388
__builtin_ppc_dcbz(c);
377389
}
390+
391+
// CHECK-LABEL: @test_builtin_ppc_fence(
392+
// CHECK: call void @llvm.ppc.fence()
393+
// CHECK-NEXT: ret void
394+
//
395+
// CHECK-32-LABEL: @test_builtin_ppc_fence(
396+
// CHECK-32: call void @llvm.ppc.fence()
397+
// CHECK-32-NEXT: ret void
398+
//
399+
void test_builtin_ppc_fence() {
400+
__builtin_ppc_fence();
401+
}

llvm/include/llvm/IR/IntrinsicsPowerPC.td

+5
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.".
2929
[IntrArgMemOnly, NoCapture<ArgIndex<0>>, ImmArg<ArgIndex<1>>]>;
3030
def int_ppc_dcbzl : Intrinsic<[], [llvm_ptr_ty], []>;
3131

32+
// Emit pseudo instruction as fence of instruction motion
33+
def int_ppc_fence : ClangBuiltin<"__builtin_ppc_fence">,
34+
DefaultAttrsIntrinsic<[], [],
35+
[IntrNoMerge, IntrHasSideEffects]>;
36+
3237
// Get content from current FPSCR register
3338
def int_ppc_readflm : ClangBuiltin<"__builtin_readflm">,
3439
DefaultAttrsIntrinsic<[llvm_double_ty], [],

llvm/lib/Target/PowerPC/PPCInstrInfo.cpp

+7-1
Original file line numberDiff line numberDiff line change
@@ -2155,11 +2155,17 @@ bool PPCInstrInfo::isPredicated(const MachineInstr &MI) const {
21552155
bool PPCInstrInfo::isSchedulingBoundary(const MachineInstr &MI,
21562156
const MachineBasicBlock *MBB,
21572157
const MachineFunction &MF) const {
2158+
switch (MI.getOpcode()) {
2159+
default:
2160+
break;
21582161
// Set MFFS and MTFSF as scheduling boundary to avoid unexpected code motion
21592162
// across them, since some FP operations may change content of FPSCR.
21602163
// TODO: Model FPSCR in PPC instruction definitions and remove the workaround
2161-
if (MI.getOpcode() == PPC::MFFS || MI.getOpcode() == PPC::MTFSF)
2164+
case PPC::MFFS:
2165+
case PPC::MTFSF:
2166+
case PPC::FENCE:
21622167
return true;
2168+
}
21632169
return TargetInstrInfo::isSchedulingBoundary(MI, MBB, MF);
21642170
}
21652171

llvm/lib/Target/PowerPC/PPCInstrInfo.td

+4
Original file line numberDiff line numberDiff line change
@@ -1328,6 +1328,9 @@ def SETFLM : PPCCustomInserterPseudo<(outs f8rc:$FRT), (ins f8rc:$FLM),
13281328
"#SETFLM", [(set f64:$FRT, (int_ppc_setflm f8rc:$FLM))]>;
13291329
}
13301330

1331+
let isBarrier = 1, hasSideEffects = 1, Defs = [RM] in
1332+
def FENCE : PPCEmitTimePseudo<(outs), (ins), "#FENCE", []>;
1333+
13311334
let Defs = [LR] in
13321335
def MovePCtoLR : PPCEmitTimePseudo<(outs), (ins), "#MovePCtoLR", []>,
13331336
PPC970_Unit_BRU;
@@ -3187,6 +3190,7 @@ def : Pat<(PPCtc_return (i32 texternalsym:$dst), imm:$imm),
31873190
def : Pat<(PPCtc_return CTRRC:$dst, imm:$imm),
31883191
(TCRETURNri CTRRC:$dst, imm:$imm)>;
31893192

3193+
def : Pat<(int_ppc_fence), (FENCE)>;
31903194
def : Pat<(int_ppc_readflm), (MFFS)>;
31913195
def : Pat<(int_ppc_mffsl), (MFFSL)>;
31923196

llvm/test/CodeGen/PowerPC/fence.ll

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2+
; RUN: llc -verify-machineinstrs -mtriple=powerpc64-ibm-aix \
3+
; RUN: -mcpu=pwr7 < %s | FileCheck %s
4+
; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux \
5+
; RUN: -mcpu=pwr8 < %s | FileCheck %s
6+
; RUN: llc < %s -mtriple powerpc64le-unknown-linux -debug-only=machine-scheduler \
7+
; RUN: 2>&1 | FileCheck %s --check-prefix=LOG
8+
9+
define dso_local void @test_builtin_ppc_fence() {
10+
; CHECK-LABEL: test_builtin_ppc_fence:
11+
; CHECK: # %bb.0: # %entry
12+
; CHECK-NEXT: #FENCE
13+
; CHECK-NEXT: blr
14+
entry:
15+
call void @llvm.ppc.fence()
16+
ret void
17+
}
18+
declare void @llvm.ppc.fence()
19+
20+
; LOG: ***** MI Scheduling *****
21+
; LOG-NEXT: motion:%bb.0 entry
22+
; LOG: ExitSU: FENCE implicit-def dead $rm
23+
; LOG: ***** MI Scheduling *****
24+
; LOG-NEXT: motion:%bb.0 entry
25+
; LOG: ExitSU: FENCE implicit-def dead $rm
26+
;
27+
; LOG: ***** MI Scheduling *****
28+
; LOG-NEXT: motion:%bb.0 entry
29+
; LOG: ExitSU: FENCE implicit-def dead $rm
30+
; LOG: ***** MI Scheduling *****
31+
; LOG-NEXT: motion:%bb.0 entry
32+
; LOG: ExitSU: FENCE implicit-def dead $rm
33+
define double @motion(double %a, double %b, double %c, double %d) {
34+
entry:
35+
%0 = fdiv double %a, %b
36+
%1 = fdiv double %b, %d
37+
call void @llvm.ppc.fence()
38+
%2 = fdiv double %c, %d
39+
%3 = fdiv double %a, %c
40+
call void @llvm.ppc.fence()
41+
%4 = fadd double %0, %1
42+
%5 = fadd double %2, %3
43+
%6 = fsub double %4, %5
44+
ret double %6
45+
}

0 commit comments

Comments
 (0)