Skip to content

Commit 88cc292

Browse files
lei137memfrob
authored andcommitted
[PowerPC] Implement XL compact math builtins
Implement a subset of builtins required for compatiblilty with AIX XL compiler. Reviewed By: nemanjai Differential Revision: https://reviews.llvm.org/D105930
1 parent bf66672 commit 88cc292

File tree

13 files changed

+625
-8
lines changed

13 files changed

+625
-8
lines changed

clang/include/clang/Basic/BuiltinsPPC.def

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
#define UNALIASED_CUSTOM_BUILTIN(ID, TYPES, ACCUMULATE) \
3030
CUSTOM_BUILTIN(ID, ID, TYPES, ACCUMULATE)
3131

32-
// builtins for compatibility with the XL compiler
32+
// XL Compatibility built-ins
3333
BUILTIN(__builtin_ppc_popcntb, "ULiULi", "")
3434
BUILTIN(__builtin_ppc_poppar4, "iUi", "")
3535
BUILTIN(__builtin_ppc_poppar8, "iULLi", "")
@@ -97,6 +97,21 @@ BUILTIN(__builtin_ppc_load8r, "ULLiULLi*", "")
9797
BUILTIN(__builtin_ppc_store2r, "vUiUs*", "")
9898
BUILTIN(__builtin_ppc_store4r, "vUiUi*", "")
9999
BUILTIN(__builtin_ppc_store8r, "vULLiULLi*", "")
100+
BUILTIN(__builtin_ppc_extract_exp, "Uid", "")
101+
BUILTIN(__builtin_ppc_extract_sig, "ULLid", "")
102+
BUILTIN(__builtin_ppc_mtfsb0, "vUIi", "")
103+
BUILTIN(__builtin_ppc_mtfsb1, "vUIi", "")
104+
BUILTIN(__builtin_ppc_mtfsf, "vUIiUi", "")
105+
BUILTIN(__builtin_ppc_mtfsfi, "vUIiUIi", "")
106+
BUILTIN(__builtin_ppc_insert_exp, "ddULLi", "")
107+
BUILTIN(__builtin_ppc_fmsub, "dddd", "")
108+
BUILTIN(__builtin_ppc_fmsubs, "ffff", "")
109+
BUILTIN(__builtin_ppc_fnmadd, "dddd", "")
110+
BUILTIN(__builtin_ppc_fnmadds, "ffff", "")
111+
BUILTIN(__builtin_ppc_fnmsub, "dddd", "")
112+
BUILTIN(__builtin_ppc_fnmsubs, "ffff", "")
113+
BUILTIN(__builtin_ppc_fre, "dd", "")
114+
BUILTIN(__builtin_ppc_fres, "ff", "")
100115

101116
BUILTIN(__builtin_ppc_get_timebase, "ULLi", "n")
102117

clang/lib/Basic/Targets/PPC.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,21 @@ static void defineXLCompatMacros(MacroBuilder &Builder) {
151151
Builder.defineMacro("__store2r", "__builtin_ppc_store2r");
152152
Builder.defineMacro("__store4r", "__builtin_ppc_store4r");
153153
Builder.defineMacro("__store8r", "__builtin_ppc_store8r");
154+
Builder.defineMacro("__extract_exp", "__builtin_ppc_extract_exp");
155+
Builder.defineMacro("__extract_sig", "__builtin_ppc_extract_sig");
156+
Builder.defineMacro("__mtfsb0", "__builtin_ppc_mtfsb0");
157+
Builder.defineMacro("__mtfsb1", "__builtin_ppc_mtfsb1");
158+
Builder.defineMacro("__mtfsf", "__builtin_ppc_mtfsf");
159+
Builder.defineMacro("__mtfsfi", "__builtin_ppc_mtfsfi");
160+
Builder.defineMacro("__insert_exp", "__builtin_ppc_insert_exp");
161+
Builder.defineMacro("__fmsub", "__builtin_ppc_fmsub");
162+
Builder.defineMacro("__fmsubs", "__builtin_ppc_fmsubs");
163+
Builder.defineMacro("__fnmadd", "__builtin_ppc_fnmadd");
164+
Builder.defineMacro("__fnmadds", "__builtin_ppc_fnmadds");
165+
Builder.defineMacro("__fnmsub", "__builtin_ppc_fnmsub");
166+
Builder.defineMacro("__fnmsubs", "__builtin_ppc_fnmsubs");
167+
Builder.defineMacro("__fre", "__builtin_ppc_fre");
168+
Builder.defineMacro("__fres", "__builtin_ppc_fres");
154169
}
155170

156171
/// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific

clang/lib/Sema/SemaChecking.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3278,6 +3278,8 @@ static bool isPPC_64Builtin(unsigned BuiltinID) {
32783278
case PPC::BI__builtin_ppc_maddld:
32793279
case PPC::BI__builtin_ppc_load8r:
32803280
case PPC::BI__builtin_ppc_store8r:
3281+
case PPC::BI__builtin_ppc_insert_exp:
3282+
case PPC::BI__builtin_ppc_extract_sig:
32813283
return true;
32823284
}
32833285
return false;
@@ -3414,6 +3416,19 @@ bool Sema::CheckPPCBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID,
34143416
case PPC::BI__builtin_ppc_rldimi:
34153417
return SemaBuiltinConstantArg(TheCall, 2, Result) ||
34163418
SemaValueIsRunOfOnes(TheCall, 3);
3419+
case PPC::BI__builtin_ppc_extract_exp:
3420+
case PPC::BI__builtin_ppc_extract_sig:
3421+
case PPC::BI__builtin_ppc_insert_exp:
3422+
return SemaFeatureCheck(*this, TheCall, "power9-vector",
3423+
diag::err_ppc_builtin_only_on_arch, "9");
3424+
case PPC::BI__builtin_ppc_mtfsb0:
3425+
case PPC::BI__builtin_ppc_mtfsb1:
3426+
return SemaBuiltinConstantArgRange(TheCall, 0, 0, 31);
3427+
case PPC::BI__builtin_ppc_mtfsf:
3428+
return SemaBuiltinConstantArgRange(TheCall, 0, 0, 255);
3429+
case PPC::BI__builtin_ppc_mtfsfi:
3430+
return SemaBuiltinConstantArgRange(TheCall, 0, 0, 7) ||
3431+
SemaBuiltinConstantArgRange(TheCall, 1, 0, 15);
34173432
#define CUSTOM_BUILTIN(Name, Intr, Types, Acc) \
34183433
case PPC::BI__builtin_##Name: \
34193434
return SemaBuiltinPPCMMACall(TheCall, Types);

clang/test/CodeGen/builtins-ppc-xlcompat-error.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,20 @@ void test_builtin_ppc_rlwnm() {
4343
res = __builtin_ppc_rlwnm(ui, 31, mask); // expected-error {{argument to '__builtin_ppc_rlwnm' must be a constant integer}}
4444
res = __builtin_ppc_rlwnm(ui, 31, 0xFF0F0F00); // expected-error {{argument 2 value should represent a contiguous bit field}}
4545
}
46+
47+
extern unsigned int usi;
48+
extern double d;
49+
extern float f;
50+
51+
void testMathBuiltin(void) {
52+
__mtfsb0(usi); //expected-error {{argument to '__builtin_ppc_mtfsb0' must be a constant integer}}
53+
__mtfsb0(32); //expected-error {{argument value 32 is outside the valid range [0, 31]}}
54+
__mtfsb1(usi); //expected-error {{argument to '__builtin_ppc_mtfsb1' must be a constant integer}}
55+
__mtfsb1(45); //expected-error {{argument value 45 is outside the valid range [0, 31]}}
56+
__mtfsf(usi, usi); //expected-error {{argument to '__builtin_ppc_mtfsf' must be a constant integer}}
57+
__mtfsf(350, usi); //expected-error {{argument value 350 is outside the valid range [0, 255]}}
58+
__mtfsfi(usi, 0); //expected-error {{argument to '__builtin_ppc_mtfsfi' must be a constant integer}}
59+
__mtfsfi(0, usi); //expected-error {{argument to '__builtin_ppc_mtfsfi' must be a constant integer}}
60+
__mtfsfi(8, 0); //expected-error {{argument value 8 is outside the valid range [0, 7]}}
61+
__mtfsfi(5, 24); //expected-error {{argument value 24 is outside the valid range [0, 15]}}
62+
}
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
// RUN: %clang_cc1 -triple powerpc64-unknown-unknown -emit-llvm %s \
2+
// RUN: -target-cpu pwr7 -o - | FileCheck %s
3+
// RUN: %clang_cc1 -triple powerpc64le-unknown-unknown -emit-llvm %s \
4+
// RUN: -target-cpu pwr8 -o - | FileCheck %s
5+
// RUN: %clang_cc1 -triple powerpc64-unknown-aix -emit-llvm %s \
6+
// RUN: -target-cpu pwr7 -o - | FileCheck %s
7+
// RUN: %clang_cc1 -triple powerpc-unknown-aix -emit-llvm %s \
8+
// RUN: -target-cpu pwr7 -o - | FileCheck %s
9+
10+
// CHECK-LABEL: @mtfsb0(
11+
// CHECK: call void @llvm.ppc.mtfsb0(i32 10)
12+
// CHECK-NEXT: ret void
13+
//
14+
void mtfsb0 () {
15+
__mtfsb0 (10);
16+
}
17+
18+
// CHECK-LABEL: @mtfsb1(
19+
// CHECK: call void @llvm.ppc.mtfsb1(i32 0)
20+
// CHECK-NEXT: ret void
21+
//
22+
void mtfsb1 () {
23+
__mtfsb1 (0);
24+
}
25+
26+
// CHECK-LABEL: @mtfsf(
27+
// CHECK: [[UI_ADDR:%.*]] = alloca i32, align 4
28+
// CHECK-NEXT: store i32 [[UI:%.*]], i32* [[UI_ADDR]], align 4
29+
// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[UI_ADDR]], align 4
30+
// CHECK-NEXT: call void @llvm.ppc.mtfsf(i32 8, i32 [[TMP0]])
31+
// CHECK-NEXT: ret void
32+
//
33+
void mtfsf (unsigned int ui) {
34+
__mtfsf (8, ui);
35+
}
36+
37+
// CHECK-LABEL: @mtfsfi(
38+
// CHECK: call void @llvm.ppc.mtfsfi(i32 7, i32 15)
39+
// CHECK-NEXT: ret void
40+
//
41+
void mtfsfi () {
42+
__mtfsfi (7, 15);
43+
}
44+
45+
// CHECK-LABEL: @fmsub(
46+
// CHECK: [[D_ADDR:%.*]] = alloca double, align 8
47+
// CHECK-NEXT: store double [[D:%.*]], double* [[D_ADDR]], align 8
48+
// CHECK-NEXT: [[TMP0:%.*]] = load double, double* [[D_ADDR]], align 8
49+
// CHECK-NEXT: [[TMP1:%.*]] = load double, double* [[D_ADDR]], align 8
50+
// CHECK-NEXT: [[TMP2:%.*]] = load double, double* [[D_ADDR]], align 8
51+
// CHECK-NEXT: [[TMP3:%.*]] = call double @llvm.ppc.fmsub(double [[TMP0]], double [[TMP1]], double [[TMP2]])
52+
// CHECK-NEXT: ret double [[TMP3]]
53+
//
54+
double fmsub (double d) {
55+
return __fmsub (d, d, d);
56+
}
57+
58+
// CHECK-LABEL: @fmsubs(
59+
// CHECK: [[F_ADDR:%.*]] = alloca float, align 4
60+
// CHECK-NEXT: store float [[F:%.*]], float* [[F_ADDR]], align 4
61+
// CHECK-NEXT: [[TMP0:%.*]] = load float, float* [[F_ADDR]], align 4
62+
// CHECK-NEXT: [[TMP1:%.*]] = load float, float* [[F_ADDR]], align 4
63+
// CHECK-NEXT: [[TMP2:%.*]] = load float, float* [[F_ADDR]], align 4
64+
// CHECK-NEXT: [[TMP3:%.*]] = call float @llvm.ppc.fmsubs(float [[TMP0]], float [[TMP1]], float [[TMP2]])
65+
// CHECK-NEXT: ret float [[TMP3]]
66+
//
67+
float fmsubs (float f) {
68+
return __fmsubs (f, f, f);
69+
}
70+
71+
// CHECK-LABEL: @fnmadd(
72+
// CHECK: [[D_ADDR:%.*]] = alloca double, align 8
73+
// CHECK-NEXT: store double [[D:%.*]], double* [[D_ADDR]], align 8
74+
// CHECK-NEXT: [[TMP0:%.*]] = load double, double* [[D_ADDR]], align 8
75+
// CHECK-NEXT: [[TMP1:%.*]] = load double, double* [[D_ADDR]], align 8
76+
// CHECK-NEXT: [[TMP2:%.*]] = load double, double* [[D_ADDR]], align 8
77+
// CHECK-NEXT: [[TMP3:%.*]] = call double @llvm.ppc.fnmadd(double [[TMP0]], double [[TMP1]], double [[TMP2]])
78+
// CHECK-NEXT: ret double [[TMP3]]
79+
//
80+
double fnmadd (double d) {
81+
return __fnmadd (d, d, d);
82+
}
83+
84+
// CHECK-LABEL: @fnmadds(
85+
// CHECK: [[F_ADDR:%.*]] = alloca float, align 4
86+
// CHECK-NEXT: store float [[F:%.*]], float* [[F_ADDR]], align 4
87+
// CHECK-NEXT: [[TMP0:%.*]] = load float, float* [[F_ADDR]], align 4
88+
// CHECK-NEXT: [[TMP1:%.*]] = load float, float* [[F_ADDR]], align 4
89+
// CHECK-NEXT: [[TMP2:%.*]] = load float, float* [[F_ADDR]], align 4
90+
// CHECK-NEXT: [[TMP3:%.*]] = call float @llvm.ppc.fnmadds(float [[TMP0]], float [[TMP1]], float [[TMP2]])
91+
// CHECK-NEXT: ret float [[TMP3]]
92+
//
93+
float fnmadds (float f) {
94+
return __fnmadds (f, f, f);
95+
}
96+
97+
// CHECK-LABEL: @fnmsub(
98+
// CHECK: [[D_ADDR:%.*]] = alloca double, align 8
99+
// CHECK-NEXT: store double [[D:%.*]], double* [[D_ADDR]], align 8
100+
// CHECK-NEXT: [[TMP0:%.*]] = load double, double* [[D_ADDR]], align 8
101+
// CHECK-NEXT: [[TMP1:%.*]] = load double, double* [[D_ADDR]], align 8
102+
// CHECK-NEXT: [[TMP2:%.*]] = load double, double* [[D_ADDR]], align 8
103+
// CHECK-NEXT: [[TMP3:%.*]] = call double @llvm.ppc.fnmsub(double [[TMP0]], double [[TMP1]], double [[TMP2]])
104+
// CHECK-NEXT: ret double [[TMP3]]
105+
//
106+
double fnmsub (double d) {
107+
return __fnmsub (d, d, d);
108+
}
109+
110+
// CHECK-LABEL: @fnmsubs(
111+
// CHECK: [[F_ADDR:%.*]] = alloca float, align 4
112+
// CHECK-NEXT: store float [[F:%.*]], float* [[F_ADDR]], align 4
113+
// CHECK-NEXT: [[TMP0:%.*]] = load float, float* [[F_ADDR]], align 4
114+
// CHECK-NEXT: [[TMP1:%.*]] = load float, float* [[F_ADDR]], align 4
115+
// CHECK-NEXT: [[TMP2:%.*]] = load float, float* [[F_ADDR]], align 4
116+
// CHECK-NEXT: [[TMP3:%.*]] = call float @llvm.ppc.fnmsubs(float [[TMP0]], float [[TMP1]], float [[TMP2]])
117+
// CHECK-NEXT: ret float [[TMP3]]
118+
//
119+
float fnmsubs (float f) {
120+
return __fnmsubs (f, f, f);
121+
}
122+
123+
// CHECK-LABEL: @fre(
124+
// CHECK: [[D_ADDR:%.*]] = alloca double, align 8
125+
// CHECK-NEXT: store double [[D:%.*]], double* [[D_ADDR]], align 8
126+
// CHECK-NEXT: [[TMP0:%.*]] = load double, double* [[D_ADDR]], align 8
127+
// CHECK-NEXT: [[TMP1:%.*]] = call double @llvm.ppc.fre(double [[TMP0]])
128+
// CHECK-NEXT: ret double [[TMP1]]
129+
//
130+
double fre (double d) {
131+
return __fre (d);
132+
}
133+
134+
// CHECK-LABEL: @fres(
135+
// CHECK: [[F_ADDR:%.*]] = alloca float, align 4
136+
// CHECK-NEXT: store float [[F:%.*]], float* [[F_ADDR]], align 4
137+
// CHECK-NEXT: [[TMP0:%.*]] = load float, float* [[F_ADDR]], align 4
138+
// CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.ppc.fres(float [[TMP0]])
139+
// CHECK-NEXT: ret float [[TMP1]]
140+
//
141+
float fres (float f) {
142+
return __fres (f);
143+
}

clang/test/CodeGen/builtins-ppc-xlcompat-pwr9-64bit.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,23 @@ unsigned long long test_builtin_ppc_maddld_unsigned() {
6060
// CHECK-NONPWR9-ERR: error: this builtin is only valid on POWER9 or later CPUs
6161
return __builtin_ppc_maddld(ull, ull, ull);
6262
}
63+
64+
unsigned long long extract_sig (double d) {
65+
// CHECK-LABEL: @extract_sig(
66+
// CHECK: [[TMP1:%.*]] = call i64 @llvm.ppc.extract.sig(double %0)
67+
// CHECK-NEXT: ret i64 [[TMP1]]
68+
//
69+
// CHECK-32-ERROR: error: this builtin is only available on 64-bit targets
70+
// CHECK-NONPWR9-ERR: error: this builtin is only valid on POWER9 or later CPUs
71+
return __extract_sig (d);
72+
}
73+
74+
double insert_exp (double d, unsigned long long ull) {
75+
// CHECK-LABEL: @insert_exp(
76+
// CHECK: [[TMP2:%.*]] = call double @llvm.ppc.insert.exp(double %0, i64 %1)
77+
// CHECK-NEXT: ret double [[TMP2]]
78+
//
79+
// CHECK-32-ERROR: error: this builtin is only available on 64-bit targets
80+
// CHECK-NONPWR9-ERR: error: this builtin is only valid on POWER9 or later CPUs
81+
return __insert_exp (d, ull);
82+
}

clang/test/CodeGen/builtins-ppc-xlcompat-pwr9.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,11 @@ int test_builtin_ppc_cmprb() {
1919
// CHECK-NONPWR9-ERR: error: this builtin is only valid on POWER9 or later CPUs
2020
return __builtin_ppc_cmprb(0, ui, ui) + __builtin_ppc_cmprb(1, ui, ui);
2121
}
22+
23+
unsigned int extract_exp (double d) {
24+
// CHECK-LABEL: @extract_exp
25+
// CHECK: [[TMP1:%.*]] = call i32 @llvm.ppc.extract.exp(double %0)
26+
// CHECK-NEXT: ret i32 [[TMP1]]
27+
// CHECK-NONPWR9-ERR: error: this builtin is only valid on POWER9 or later CPUs
28+
return __extract_exp (d);
29+
}

llvm/include/llvm/IR/IntrinsicsPowerPC.td

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1618,6 +1618,69 @@ let TargetPrefix = "ppc" in {
16181618
def int_ppc_store8r
16191619
: GCCBuiltin<"__builtin_ppc_store8r">,
16201620
Intrinsic<[], [llvm_i64_ty, llvm_ptr_ty], [IntrWriteMem]>;
1621+
def int_ppc_insert_exp
1622+
: GCCBuiltin<"__builtin_ppc_insert_exp">,
1623+
Intrinsic <[llvm_double_ty], [llvm_double_ty, llvm_i64_ty],
1624+
[IntrNoMem]>;
1625+
def int_ppc_extract_exp
1626+
: GCCBuiltin<"__builtin_ppc_extract_exp">,
1627+
Intrinsic <[llvm_i32_ty], [llvm_double_ty], [IntrNoMem]>;
1628+
def int_ppc_extract_sig
1629+
: GCCBuiltin<"__builtin_ppc_extract_sig">,
1630+
Intrinsic <[llvm_i64_ty], [llvm_double_ty], [IntrNoMem]>;
1631+
def int_ppc_mtfsb0
1632+
: GCCBuiltin<"__builtin_ppc_mtfsb0">,
1633+
Intrinsic <[], [llvm_i32_ty],
1634+
[IntrNoMem, IntrHasSideEffects, ImmArg<ArgIndex<0>>]>;
1635+
def int_ppc_mtfsb1
1636+
: GCCBuiltin<"__builtin_ppc_mtfsb1">,
1637+
Intrinsic <[], [llvm_i32_ty],
1638+
[IntrNoMem, IntrHasSideEffects, ImmArg<ArgIndex<0>>]>;
1639+
def int_ppc_mtfsf
1640+
: GCCBuiltin<"__builtin_ppc_mtfsf">,
1641+
Intrinsic <[], [llvm_i32_ty, llvm_i32_ty],
1642+
[IntrNoMem, IntrHasSideEffects, ImmArg<ArgIndex<0>>]>;
1643+
def int_ppc_mtfsfi
1644+
: GCCBuiltin<"__builtin_ppc_mtfsfi">,
1645+
Intrinsic <[], [llvm_i32_ty, llvm_i32_ty],
1646+
[IntrNoMem, IntrHasSideEffects,
1647+
ImmArg<ArgIndex<0>>,ImmArg<ArgIndex<1>>]>;
1648+
def int_ppc_fmsub
1649+
: GCCBuiltin<"__builtin_ppc_fmsub">,
1650+
Intrinsic <[llvm_double_ty],
1651+
[llvm_double_ty, llvm_double_ty, llvm_double_ty],
1652+
[IntrNoMem]>;
1653+
def int_ppc_fmsubs
1654+
: GCCBuiltin<"__builtin_ppc_fmsubs">,
1655+
Intrinsic <[llvm_float_ty],
1656+
[llvm_float_ty, llvm_float_ty, llvm_float_ty],
1657+
[IntrNoMem]>;
1658+
def int_ppc_fnmadd
1659+
: GCCBuiltin<"__builtin_ppc_fnmadd">,
1660+
Intrinsic <[llvm_double_ty],
1661+
[llvm_double_ty, llvm_double_ty, llvm_double_ty],
1662+
[IntrNoMem]>;
1663+
def int_ppc_fnmadds
1664+
: GCCBuiltin<"__builtin_ppc_fnmadds">,
1665+
Intrinsic <[llvm_float_ty],
1666+
[llvm_float_ty, llvm_float_ty, llvm_float_ty],
1667+
[IntrNoMem]>;
1668+
def int_ppc_fnmsub
1669+
: GCCBuiltin<"__builtin_ppc_fnmsub">,
1670+
Intrinsic <[llvm_double_ty],
1671+
[llvm_double_ty, llvm_double_ty, llvm_double_ty],
1672+
[IntrNoMem]>;
1673+
def int_ppc_fnmsubs
1674+
: GCCBuiltin<"__builtin_ppc_fnmsubs">,
1675+
Intrinsic <[llvm_float_ty],
1676+
[llvm_float_ty, llvm_float_ty, llvm_float_ty],
1677+
[IntrNoMem]>;
1678+
def int_ppc_fre
1679+
: GCCBuiltin<"__builtin_ppc_fre">,
1680+
Intrinsic <[llvm_double_ty], [llvm_double_ty], [IntrNoMem]>;
1681+
def int_ppc_fres
1682+
: GCCBuiltin<"__builtin_ppc_fres">,
1683+
Intrinsic <[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
16211684
}
16221685

16231686
//===----------------------------------------------------------------------===//

llvm/lib/Target/PowerPC/PPCInstrInfo.td

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3089,12 +3089,16 @@ let Uses = [RM], mayRaiseFPException = 1 in {
30893089

30903090
// When FM is 30/31, we are setting the 62/63 bit of FPSCR, the implicit-def
30913091
// RM should be set.
3092+
let hasSideEffects = 1 in {
30923093
def MTFSB0 : XForm_43<63, 70, (outs), (ins u5imm:$FM),
3093-
"mtfsb0 $FM", IIC_IntMTFSB0, []>,
3094+
"mtfsb0 $FM", IIC_IntMTFSB0,
3095+
[(int_ppc_mtfsb0 timm:$FM)]>,
30943096
PPC970_DGroup_Single, PPC970_Unit_FPU;
30953097
def MTFSB1 : XForm_43<63, 38, (outs), (ins u5imm:$FM),
3096-
"mtfsb1 $FM", IIC_IntMTFSB0, []>,
3098+
"mtfsb1 $FM", IIC_IntMTFSB0,
3099+
[(int_ppc_mtfsb1 timm:$FM)]>,
30973100
PPC970_DGroup_Single, PPC970_Unit_FPU;
3101+
}
30983102

30993103
let Defs = [RM] in {
31003104
let isCodeGenOnly = 1 in
@@ -3647,6 +3651,16 @@ def : Pat<(fcopysign f32:$frB, f64:$frA),
36473651
(FCPSGNS (COPY_TO_REGCLASS $frA, F4RC), $frB)>;
36483652
}
36493653

3654+
// XL Compat intrinsics.
3655+
def : Pat<(int_ppc_fmsub f64:$A, f64:$B, f64:$C), (FMSUB $A, $B, $C)>;
3656+
def : Pat<(int_ppc_fmsubs f32:$A, f32:$B, f32:$C), (FMSUBS $A, $B, $C)>;
3657+
def : Pat<(int_ppc_fnmsub f64:$A, f64:$B, f64:$C), (FNMSUB $A, $B, $C)>;
3658+
def : Pat<(int_ppc_fnmsubs f32:$A, f32:$B, f32:$C), (FNMSUBS $A, $B, $C)>;
3659+
def : Pat<(int_ppc_fnmadd f64:$A, f64:$B, f64:$C), (FNMADD $A, $B, $C)>;
3660+
def : Pat<(int_ppc_fnmadds f32:$A, f32:$B, f32:$C), (FNMADDS $A, $B, $C)>;
3661+
def : Pat<(int_ppc_fre f64:$A), (FRE $A)>;
3662+
def : Pat<(int_ppc_fres f32:$A), (FRES $A)>;
3663+
36503664
include "PPCInstrAltivec.td"
36513665
include "PPCInstrSPE.td"
36523666
include "PPCInstr64Bit.td"

0 commit comments

Comments
 (0)