forked from OSchip/llvm-project
[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
This commit is contained in:
parent
472fa04de8
commit
8930af45c3
|
@ -144,6 +144,7 @@ BUILTIN(__builtin_ppc_mfspr, "ULiIi", "")
|
||||||
BUILTIN(__builtin_ppc_mtmsr, "vUi", "")
|
BUILTIN(__builtin_ppc_mtmsr, "vUi", "")
|
||||||
BUILTIN(__builtin_ppc_mtspr, "vIiULi", "")
|
BUILTIN(__builtin_ppc_mtspr, "vIiULi", "")
|
||||||
BUILTIN(__builtin_ppc_stfiw, "viC*d", "")
|
BUILTIN(__builtin_ppc_stfiw, "viC*d", "")
|
||||||
|
BUILTIN(__builtin_ppc_addex, "LLiLLiLLiCIi", "")
|
||||||
|
|
||||||
BUILTIN(__builtin_ppc_get_timebase, "ULLi", "n")
|
BUILTIN(__builtin_ppc_get_timebase, "ULLi", "n")
|
||||||
|
|
||||||
|
|
|
@ -9733,6 +9733,9 @@ def err_argument_invalid_range : Error<
|
||||||
def warn_argument_invalid_range : Warning<
|
def warn_argument_invalid_range : Warning<
|
||||||
"argument value %0 is outside the valid range [%1, %2]">, DefaultError,
|
"argument value %0 is outside the valid range [%1, %2]">, DefaultError,
|
||||||
InGroup<DiagGroup<"argument-outside-range">>;
|
InGroup<DiagGroup<"argument-outside-range">>;
|
||||||
|
def warn_argument_undefined_behaviour : Warning<
|
||||||
|
"argument value %0 will result in undefined behaviour">,
|
||||||
|
InGroup<DiagGroup<"argument-undefined-behaviour">>;
|
||||||
def err_argument_not_multiple : Error<
|
def err_argument_not_multiple : Error<
|
||||||
"argument should be a multiple of %0">;
|
"argument should be a multiple of %0">;
|
||||||
def err_argument_not_power_of_2 : Error<
|
def err_argument_not_power_of_2 : Error<
|
||||||
|
|
|
@ -236,6 +236,7 @@ static void defineXLCompatMacros(MacroBuilder &Builder) {
|
||||||
Builder.defineMacro("__frsqrtes", "__builtin_ppc_frsqrtes");
|
Builder.defineMacro("__frsqrtes", "__builtin_ppc_frsqrtes");
|
||||||
Builder.defineMacro("__fsqrt", "__builtin_ppc_fsqrt");
|
Builder.defineMacro("__fsqrt", "__builtin_ppc_fsqrt");
|
||||||
Builder.defineMacro("__fsqrts", "__builtin_ppc_fsqrts");
|
Builder.defineMacro("__fsqrts", "__builtin_ppc_fsqrts");
|
||||||
|
Builder.defineMacro("__addex", "__builtin_ppc_addex");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific
|
/// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific
|
||||||
|
|
|
@ -3294,6 +3294,7 @@ static bool isPPC_64Builtin(unsigned BuiltinID) {
|
||||||
case PPC::BI__builtin_ppc_store8r:
|
case PPC::BI__builtin_ppc_store8r:
|
||||||
case PPC::BI__builtin_ppc_insert_exp:
|
case PPC::BI__builtin_ppc_insert_exp:
|
||||||
case PPC::BI__builtin_ppc_extract_sig:
|
case PPC::BI__builtin_ppc_extract_sig:
|
||||||
|
case PPC::BI__builtin_ppc_addex:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -3435,6 +3436,19 @@ bool Sema::CheckPPCBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID,
|
||||||
case PPC::BI__builtin_ppc_insert_exp:
|
case PPC::BI__builtin_ppc_insert_exp:
|
||||||
return SemaFeatureCheck(*this, TheCall, "power9-vector",
|
return SemaFeatureCheck(*this, TheCall, "power9-vector",
|
||||||
diag::err_ppc_builtin_only_on_arch, "9");
|
diag::err_ppc_builtin_only_on_arch, "9");
|
||||||
|
case PPC::BI__builtin_ppc_addex: {
|
||||||
|
if (SemaFeatureCheck(*this, TheCall, "isa-v30-instructions",
|
||||||
|
diag::err_ppc_builtin_only_on_arch, "9") ||
|
||||||
|
SemaBuiltinConstantArgRange(TheCall, 2, 0, 3))
|
||||||
|
return true;
|
||||||
|
// Output warning for reserved values 1 to 3.
|
||||||
|
int ArgValue =
|
||||||
|
TheCall->getArg(2)->getIntegerConstantExpr(Context)->getSExtValue();
|
||||||
|
if (ArgValue != 0)
|
||||||
|
Diag(TheCall->getBeginLoc(), diag::warn_argument_undefined_behaviour)
|
||||||
|
<< ArgValue;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
case PPC::BI__builtin_ppc_mtfsb0:
|
case PPC::BI__builtin_ppc_mtfsb0:
|
||||||
case PPC::BI__builtin_ppc_mtfsb1:
|
case PPC::BI__builtin_ppc_mtfsb1:
|
||||||
return SemaBuiltinConstantArgRange(TheCall, 0, 0, 31);
|
return SemaBuiltinConstantArgRange(TheCall, 0, 0, 31);
|
||||||
|
|
|
@ -80,3 +80,19 @@ double insert_exp (double d, unsigned long long ull) {
|
||||||
// CHECK-NONPWR9-ERR: error: this builtin is only valid on POWER9 or later CPUs
|
// CHECK-NONPWR9-ERR: error: this builtin is only valid on POWER9 or later CPUs
|
||||||
return __insert_exp (d, ull);
|
return __insert_exp (d, ull);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
signed long long test_builtin_ppc_addex0() {
|
||||||
|
// CHECK-LABEL: @test_builtin_ppc_addex0
|
||||||
|
// CHECK: %2 = call i64 @llvm.ppc.addex(i64 %0, i64 %1, i32 0)
|
||||||
|
// CHECK-32-ERROR: error: this builtin is only available on 64-bit targets
|
||||||
|
// CHECK-NONPWR9-ERR: error: this builtin is only valid on POWER9 or later CPUs
|
||||||
|
return __builtin_ppc_addex(sll, sll, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long long test_builtin_ppc_addex1() {
|
||||||
|
// CHECK-LABEL: @test_builtin_ppc_addex1
|
||||||
|
// CHECK: %2 = call i64 @llvm.ppc.addex(i64 %0, i64 %1, i32 0)
|
||||||
|
// CHECK-32-ERROR: error: this builtin is only available on 64-bit targets
|
||||||
|
// CHECK-NONPWR9-ERR: error: this builtin is only valid on POWER9 or later CPUs
|
||||||
|
return __builtin_ppc_addex(ull, ull, 0);
|
||||||
|
}
|
||||||
|
|
|
@ -9,7 +9,18 @@
|
||||||
// RUN: -fsyntax-only -Wall -Werror -verify %s
|
// RUN: -fsyntax-only -Wall -Werror -verify %s
|
||||||
|
|
||||||
extern unsigned int ui;
|
extern unsigned int ui;
|
||||||
|
extern unsigned long long ull;
|
||||||
|
extern long long ll;
|
||||||
|
|
||||||
void test_builtin_ppc_cmprb() {
|
void test_builtin_ppc_cmprb() {
|
||||||
int res = __builtin_ppc_cmprb(3, ui, ui); // expected-error {{argument value 3 is outside the valid range [0, 1]}}
|
int res = __builtin_ppc_cmprb(3, ui, ui); // expected-error {{argument value 3 is outside the valid range [0, 1]}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __PPC64__
|
||||||
|
|
||||||
|
void test_builtin_ppc_addex() {
|
||||||
|
long long res = __builtin_ppc_addex(ll, ll, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}}
|
||||||
|
unsigned long long res2 = __builtin_ppc_addex(ull, ull, -1); // expected-error {{argument value -1 is outside the valid range [0, 3]}}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
// REQUIRES: powerpc-registered-target
|
||||||
|
// RUN: %clang_cc1 -triple powerpc64-unknown-unknown -target-cpu pwr9 \
|
||||||
|
// RUN: -verify %s
|
||||||
|
|
||||||
|
extern unsigned long long ull;
|
||||||
|
extern long long ll;
|
||||||
|
|
||||||
|
void test_builtin_ppc_addex() {
|
||||||
|
long long res = __builtin_ppc_addex(ll, ll, 1); // expected-warning {{argument value 1 will result in undefined behaviour}}
|
||||||
|
unsigned long long res2 = __builtin_ppc_addex(ull, ull, 3); // expected-warning {{argument value 3 will result in undefined behaviour}}
|
||||||
|
}
|
|
@ -1706,7 +1706,10 @@ let TargetPrefix = "ppc" in {
|
||||||
def int_ppc_fres
|
def int_ppc_fres
|
||||||
: GCCBuiltin<"__builtin_ppc_fres">,
|
: GCCBuiltin<"__builtin_ppc_fres">,
|
||||||
Intrinsic <[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
|
Intrinsic <[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
|
||||||
|
def int_ppc_addex
|
||||||
|
: GCCBuiltin<"__builtin_ppc_addex">,
|
||||||
|
Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty, llvm_i32_ty],
|
||||||
|
[IntrNoMem, IntrHasSideEffects, ImmArg<ArgIndex<2>>]>;
|
||||||
def int_ppc_fsel : GCCBuiltin<"__builtin_ppc_fsel">,
|
def int_ppc_fsel : GCCBuiltin<"__builtin_ppc_fsel">,
|
||||||
Intrinsic<[llvm_double_ty], [llvm_double_ty, llvm_double_ty,
|
Intrinsic<[llvm_double_ty], [llvm_double_ty, llvm_double_ty,
|
||||||
llvm_double_ty], [IntrNoMem]>;
|
llvm_double_ty], [IntrNoMem]>;
|
||||||
|
|
|
@ -1430,5 +1430,6 @@ def : InstRW<[],
|
||||||
DCBI,
|
DCBI,
|
||||||
DCCCI,
|
DCCCI,
|
||||||
ICCCI,
|
ICCCI,
|
||||||
ADDEX
|
ADDEX,
|
||||||
|
ADDEX8
|
||||||
)> { let Unsupported = 1; }
|
)> { let Unsupported = 1; }
|
||||||
|
|
|
@ -1670,6 +1670,13 @@ def HASHCHKP : XForm_XD6_RA5_RB5<31, 690, (outs),
|
||||||
"hashchkp $RB, $D_RA_XD", IIC_IntGeneral, []>;
|
"hashchkp $RB, $D_RA_XD", IIC_IntGeneral, []>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let Interpretation64Bit = 1, isCodeGenOnly = 1, hasSideEffects = 1 in
|
||||||
|
def ADDEX8 : Z23Form_RTAB5_CY2<31, 170, (outs g8rc:$rT),
|
||||||
|
(ins g8rc:$rA, g8rc:$rB, u2imm:$CY),
|
||||||
|
"addex $rT, $rA, $rB, $CY", IIC_IntGeneral,
|
||||||
|
[(set i64:$rT, (int_ppc_addex i64:$rA, i64:$rB,
|
||||||
|
timm:$CY))]>;
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Instruction Patterns
|
// Instruction Patterns
|
||||||
//
|
//
|
||||||
|
|
|
@ -29,3 +29,14 @@ entry:
|
||||||
ret double %0
|
ret double %0
|
||||||
}
|
}
|
||||||
declare double @llvm.ppc.insert.exp(double, i64)
|
declare double @llvm.ppc.insert.exp(double, i64)
|
||||||
|
|
||||||
|
declare i64 @llvm.ppc.addex(i64, i64, i32 immarg)
|
||||||
|
define dso_local i64 @call_addex_0(i64 %a, i64 %b) {
|
||||||
|
; CHECK-LABEL: call_addex_0:
|
||||||
|
; CHECK: # %bb.0: # %entry
|
||||||
|
; CHECK-NEXT: addex 3, 3, 4, 0
|
||||||
|
; CHECK-NEXT: blr
|
||||||
|
entry:
|
||||||
|
%0 = tail call i64 @llvm.ppc.addex(i64 %a, i64 %b, i32 0)
|
||||||
|
ret i64 %0
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue