Skip to content

Commit 8930af4

Browse files
committed
[PowerPC] Implement XL compatibility builtin __addex
Add builtin and intrinsic for `__addex`. This patch is part of a series of patches to provide builtins for compatibility with the XL compiler. Reviewed By: stefanp, nemanjai, NeHuang Differential Revision: https://reviews.llvm.org/D107002
1 parent 472fa04 commit 8930af4

File tree

11 files changed

+81
-2
lines changed

11 files changed

+81
-2
lines changed

clang/include/clang/Basic/BuiltinsPPC.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ BUILTIN(__builtin_ppc_mfspr, "ULiIi", "")
144144
BUILTIN(__builtin_ppc_mtmsr, "vUi", "")
145145
BUILTIN(__builtin_ppc_mtspr, "vIiULi", "")
146146
BUILTIN(__builtin_ppc_stfiw, "viC*d", "")
147+
BUILTIN(__builtin_ppc_addex, "LLiLLiLLiCIi", "")
147148

148149
BUILTIN(__builtin_ppc_get_timebase, "ULLi", "n")
149150

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9733,6 +9733,9 @@ def err_argument_invalid_range : Error<
97339733
def warn_argument_invalid_range : Warning<
97349734
"argument value %0 is outside the valid range [%1, %2]">, DefaultError,
97359735
InGroup<DiagGroup<"argument-outside-range">>;
9736+
def warn_argument_undefined_behaviour : Warning<
9737+
"argument value %0 will result in undefined behaviour">,
9738+
InGroup<DiagGroup<"argument-undefined-behaviour">>;
97369739
def err_argument_not_multiple : Error<
97379740
"argument should be a multiple of %0">;
97389741
def err_argument_not_power_of_2 : Error<

clang/lib/Basic/Targets/PPC.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,7 @@ static void defineXLCompatMacros(MacroBuilder &Builder) {
236236
Builder.defineMacro("__frsqrtes", "__builtin_ppc_frsqrtes");
237237
Builder.defineMacro("__fsqrt", "__builtin_ppc_fsqrt");
238238
Builder.defineMacro("__fsqrts", "__builtin_ppc_fsqrts");
239+
Builder.defineMacro("__addex", "__builtin_ppc_addex");
239240
}
240241

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

clang/lib/Sema/SemaChecking.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3294,6 +3294,7 @@ static bool isPPC_64Builtin(unsigned BuiltinID) {
32943294
case PPC::BI__builtin_ppc_store8r:
32953295
case PPC::BI__builtin_ppc_insert_exp:
32963296
case PPC::BI__builtin_ppc_extract_sig:
3297+
case PPC::BI__builtin_ppc_addex:
32973298
return true;
32983299
}
32993300
return false;
@@ -3435,6 +3436,19 @@ bool Sema::CheckPPCBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID,
34353436
case PPC::BI__builtin_ppc_insert_exp:
34363437
return SemaFeatureCheck(*this, TheCall, "power9-vector",
34373438
diag::err_ppc_builtin_only_on_arch, "9");
3439+
case PPC::BI__builtin_ppc_addex: {
3440+
if (SemaFeatureCheck(*this, TheCall, "isa-v30-instructions",
3441+
diag::err_ppc_builtin_only_on_arch, "9") ||
3442+
SemaBuiltinConstantArgRange(TheCall, 2, 0, 3))
3443+
return true;
3444+
// Output warning for reserved values 1 to 3.
3445+
int ArgValue =
3446+
TheCall->getArg(2)->getIntegerConstantExpr(Context)->getSExtValue();
3447+
if (ArgValue != 0)
3448+
Diag(TheCall->getBeginLoc(), diag::warn_argument_undefined_behaviour)
3449+
<< ArgValue;
3450+
return false;
3451+
}
34383452
case PPC::BI__builtin_ppc_mtfsb0:
34393453
case PPC::BI__builtin_ppc_mtfsb1:
34403454
return SemaBuiltinConstantArgRange(TheCall, 0, 0, 31);

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,3 +80,19 @@ double insert_exp (double d, unsigned long long ull) {
8080
// CHECK-NONPWR9-ERR: error: this builtin is only valid on POWER9 or later CPUs
8181
return __insert_exp (d, ull);
8282
}
83+
84+
signed long long test_builtin_ppc_addex0() {
85+
// CHECK-LABEL: @test_builtin_ppc_addex0
86+
// CHECK: %2 = call i64 @llvm.ppc.addex(i64 %0, i64 %1, i32 0)
87+
// CHECK-32-ERROR: error: this builtin is only available on 64-bit targets
88+
// CHECK-NONPWR9-ERR: error: this builtin is only valid on POWER9 or later CPUs
89+
return __builtin_ppc_addex(sll, sll, 0);
90+
}
91+
92+
unsigned long long test_builtin_ppc_addex1() {
93+
// CHECK-LABEL: @test_builtin_ppc_addex1
94+
// CHECK: %2 = call i64 @llvm.ppc.addex(i64 %0, i64 %1, i32 0)
95+
// CHECK-32-ERROR: error: this builtin is only available on 64-bit targets
96+
// CHECK-NONPWR9-ERR: error: this builtin is only valid on POWER9 or later CPUs
97+
return __builtin_ppc_addex(ull, ull, 0);
98+
}

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,18 @@
99
// RUN: -fsyntax-only -Wall -Werror -verify %s
1010

1111
extern unsigned int ui;
12+
extern unsigned long long ull;
13+
extern long long ll;
1214

1315
void test_builtin_ppc_cmprb() {
1416
int res = __builtin_ppc_cmprb(3, ui, ui); // expected-error {{argument value 3 is outside the valid range [0, 1]}}
1517
}
18+
19+
#ifdef __PPC64__
20+
21+
void test_builtin_ppc_addex() {
22+
long long res = __builtin_ppc_addex(ll, ll, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}}
23+
unsigned long long res2 = __builtin_ppc_addex(ull, ull, -1); // expected-error {{argument value -1 is outside the valid range [0, 3]}}
24+
}
25+
26+
#endif
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// REQUIRES: powerpc-registered-target
2+
// RUN: %clang_cc1 -triple powerpc64-unknown-unknown -target-cpu pwr9 \
3+
// RUN: -verify %s
4+
5+
extern unsigned long long ull;
6+
extern long long ll;
7+
8+
void test_builtin_ppc_addex() {
9+
long long res = __builtin_ppc_addex(ll, ll, 1); // expected-warning {{argument value 1 will result in undefined behaviour}}
10+
unsigned long long res2 = __builtin_ppc_addex(ull, ull, 3); // expected-warning {{argument value 3 will result in undefined behaviour}}
11+
}

llvm/include/llvm/IR/IntrinsicsPowerPC.td

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1706,7 +1706,10 @@ let TargetPrefix = "ppc" in {
17061706
def int_ppc_fres
17071707
: GCCBuiltin<"__builtin_ppc_fres">,
17081708
Intrinsic <[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
1709-
1709+
def int_ppc_addex
1710+
: GCCBuiltin<"__builtin_ppc_addex">,
1711+
Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty, llvm_i32_ty],
1712+
[IntrNoMem, IntrHasSideEffects, ImmArg<ArgIndex<2>>]>;
17101713
def int_ppc_fsel : GCCBuiltin<"__builtin_ppc_fsel">,
17111714
Intrinsic<[llvm_double_ty], [llvm_double_ty, llvm_double_ty,
17121715
llvm_double_ty], [IntrNoMem]>;

llvm/lib/Target/PowerPC/P9InstrResources.td

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1430,5 +1430,6 @@ def : InstRW<[],
14301430
DCBI,
14311431
DCCCI,
14321432
ICCCI,
1433-
ADDEX
1433+
ADDEX,
1434+
ADDEX8
14341435
)> { let Unsupported = 1; }

llvm/lib/Target/PowerPC/PPCInstr64Bit.td

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1670,6 +1670,13 @@ def HASHCHKP : XForm_XD6_RA5_RB5<31, 690, (outs),
16701670
"hashchkp $RB, $D_RA_XD", IIC_IntGeneral, []>;
16711671
}
16721672

1673+
let Interpretation64Bit = 1, isCodeGenOnly = 1, hasSideEffects = 1 in
1674+
def ADDEX8 : Z23Form_RTAB5_CY2<31, 170, (outs g8rc:$rT),
1675+
(ins g8rc:$rA, g8rc:$rB, u2imm:$CY),
1676+
"addex $rT, $rA, $rB, $CY", IIC_IntGeneral,
1677+
[(set i64:$rT, (int_ppc_addex i64:$rA, i64:$rB,
1678+
timm:$CY))]>;
1679+
16731680
//===----------------------------------------------------------------------===//
16741681
// Instruction Patterns
16751682
//

llvm/test/CodeGen/PowerPC/builtins-ppc-xlcompat-pwr9-64bit.ll

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,14 @@ entry:
2929
ret double %0
3030
}
3131
declare double @llvm.ppc.insert.exp(double, i64)
32+
33+
declare i64 @llvm.ppc.addex(i64, i64, i32 immarg)
34+
define dso_local i64 @call_addex_0(i64 %a, i64 %b) {
35+
; CHECK-LABEL: call_addex_0:
36+
; CHECK: # %bb.0: # %entry
37+
; CHECK-NEXT: addex 3, 3, 4, 0
38+
; CHECK-NEXT: blr
39+
entry:
40+
%0 = tail call i64 @llvm.ppc.addex(i64 %a, i64 %b, i32 0)
41+
ret i64 %0
42+
}

0 commit comments

Comments
 (0)