forked from OSchip/llvm-project
[PowerPC] FP compare and test XL compat builtins.
This patch is in a series of patches to provide builtins for compatability with the XL compiler. This patch adds builtins for compare exponent and test data class operations on floating point values. Reviewed By: #powerpc, lei Differential Revision: https://reviews.llvm.org/D109437
This commit is contained in:
parent
9e4f1f9265
commit
70391b3468
|
@ -96,6 +96,11 @@ BUILTIN(__builtin_ppc_swdiv_nochk, "ddd", "")
|
||||||
BUILTIN(__builtin_ppc_swdivs_nochk, "fff", "")
|
BUILTIN(__builtin_ppc_swdivs_nochk, "fff", "")
|
||||||
BUILTIN(__builtin_ppc_alignx, "vIivC*", "nc")
|
BUILTIN(__builtin_ppc_alignx, "vIivC*", "nc")
|
||||||
BUILTIN(__builtin_ppc_rdlam, "UWiUWiUWiUWIi", "nc")
|
BUILTIN(__builtin_ppc_rdlam, "UWiUWiUWiUWIi", "nc")
|
||||||
|
BUILTIN(__builtin_ppc_compare_exp_uo, "idd", "")
|
||||||
|
BUILTIN(__builtin_ppc_compare_exp_lt, "idd", "")
|
||||||
|
BUILTIN(__builtin_ppc_compare_exp_gt, "idd", "")
|
||||||
|
BUILTIN(__builtin_ppc_compare_exp_eq, "idd", "")
|
||||||
|
BUILTIN(__builtin_ppc_test_data_class, "idIi", "t")
|
||||||
// Compare
|
// Compare
|
||||||
BUILTIN(__builtin_ppc_cmpeqb, "LLiLLiLLi", "")
|
BUILTIN(__builtin_ppc_cmpeqb, "LLiLLiLLi", "")
|
||||||
BUILTIN(__builtin_ppc_cmprb, "iCIiii", "")
|
BUILTIN(__builtin_ppc_cmprb, "iCIiii", "")
|
||||||
|
|
|
@ -9778,8 +9778,12 @@ def err_mips_builtin_requires_msa : Error<
|
||||||
"this builtin requires 'msa' ASE, please use -mmsa">;
|
"this builtin requires 'msa' ASE, please use -mmsa">;
|
||||||
def err_ppc_builtin_only_on_arch : Error<
|
def err_ppc_builtin_only_on_arch : Error<
|
||||||
"this builtin is only valid on POWER%0 or later CPUs">;
|
"this builtin is only valid on POWER%0 or later CPUs">;
|
||||||
|
def err_ppc_builtin_requires_vsx : Error<
|
||||||
|
"this builtin requires VSX to be enabled">;
|
||||||
def err_ppc_invalid_use_mma_type : Error<
|
def err_ppc_invalid_use_mma_type : Error<
|
||||||
"invalid use of PPC MMA type">;
|
"invalid use of PPC MMA type">;
|
||||||
|
def err_ppc_invalid_test_data_class_type : Error<
|
||||||
|
"expected a 'float' or 'double' for the first argument">;
|
||||||
def err_x86_builtin_invalid_rounding : Error<
|
def err_x86_builtin_invalid_rounding : Error<
|
||||||
"invalid rounding argument">;
|
"invalid rounding argument">;
|
||||||
def err_x86_builtin_invalid_scale : Error<
|
def err_x86_builtin_invalid_scale : Error<
|
||||||
|
|
|
@ -238,6 +238,11 @@ static void defineXLCompatMacros(MacroBuilder &Builder) {
|
||||||
Builder.defineMacro("__fsqrts", "__builtin_ppc_fsqrts");
|
Builder.defineMacro("__fsqrts", "__builtin_ppc_fsqrts");
|
||||||
Builder.defineMacro("__addex", "__builtin_ppc_addex");
|
Builder.defineMacro("__addex", "__builtin_ppc_addex");
|
||||||
Builder.defineMacro("__cmplxl", "__builtin_complex");
|
Builder.defineMacro("__cmplxl", "__builtin_complex");
|
||||||
|
Builder.defineMacro("__compare_exp_uo", "__builtin_ppc_compare_exp_uo");
|
||||||
|
Builder.defineMacro("__compare_exp_lt", "__builtin_ppc_compare_exp_lt");
|
||||||
|
Builder.defineMacro("__compare_exp_gt", "__builtin_ppc_compare_exp_gt");
|
||||||
|
Builder.defineMacro("__compare_exp_eq", "__builtin_ppc_compare_exp_eq");
|
||||||
|
Builder.defineMacro("__test_data_class", "__builtin_ppc_test_data_class");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific
|
/// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific
|
||||||
|
|
|
@ -16077,6 +16077,17 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID,
|
||||||
*this, E, Intrinsic::sqrt,
|
*this, E, Intrinsic::sqrt,
|
||||||
Intrinsic::experimental_constrained_sqrt))
|
Intrinsic::experimental_constrained_sqrt))
|
||||||
.getScalarVal();
|
.getScalarVal();
|
||||||
|
case PPC::BI__builtin_ppc_test_data_class:
|
||||||
|
llvm::Type *ArgType = EmitScalarExpr(E->getArg(0))->getType();
|
||||||
|
unsigned IntrinsicID;
|
||||||
|
if (ArgType->isDoubleTy())
|
||||||
|
IntrinsicID = Intrinsic::ppc_test_data_class_d;
|
||||||
|
else if (ArgType->isFloatTy())
|
||||||
|
IntrinsicID = Intrinsic::ppc_test_data_class_f;
|
||||||
|
else
|
||||||
|
llvm_unreachable("Invalid Argument Type");
|
||||||
|
return Builder.CreateCall(CGM.getIntrinsic(IntrinsicID), Ops,
|
||||||
|
"test_data_class");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3490,6 +3490,28 @@ bool Sema::CheckPPCBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID,
|
||||||
case PPC::BI__builtin_vsx_xxgenpcvwm:
|
case PPC::BI__builtin_vsx_xxgenpcvwm:
|
||||||
case PPC::BI__builtin_vsx_xxgenpcvdm:
|
case PPC::BI__builtin_vsx_xxgenpcvdm:
|
||||||
return SemaBuiltinConstantArgRange(TheCall, 1, 0, 3);
|
return SemaBuiltinConstantArgRange(TheCall, 1, 0, 3);
|
||||||
|
case PPC::BI__builtin_ppc_compare_exp_uo:
|
||||||
|
case PPC::BI__builtin_ppc_compare_exp_lt:
|
||||||
|
case PPC::BI__builtin_ppc_compare_exp_gt:
|
||||||
|
case PPC::BI__builtin_ppc_compare_exp_eq:
|
||||||
|
return SemaFeatureCheck(*this, TheCall, "isa-v30-instructions",
|
||||||
|
diag::err_ppc_builtin_only_on_arch, "9") ||
|
||||||
|
SemaFeatureCheck(*this, TheCall, "vsx",
|
||||||
|
diag::err_ppc_builtin_requires_vsx);
|
||||||
|
case PPC::BI__builtin_ppc_test_data_class: {
|
||||||
|
// Check if the first argument of the __builtin_ppc_test_data_class call is
|
||||||
|
// valid. The argument must be either a 'float' or a 'double'.
|
||||||
|
QualType ArgType = TheCall->getArg(0)->getType();
|
||||||
|
if (ArgType != QualType(Context.FloatTy) &&
|
||||||
|
ArgType != QualType(Context.DoubleTy))
|
||||||
|
return Diag(TheCall->getBeginLoc(),
|
||||||
|
diag::err_ppc_invalid_test_data_class_type);
|
||||||
|
return SemaFeatureCheck(*this, TheCall, "isa-v30-instructions",
|
||||||
|
diag::err_ppc_builtin_only_on_arch, "9") ||
|
||||||
|
SemaFeatureCheck(*this, TheCall, "vsx",
|
||||||
|
diag::err_ppc_builtin_requires_vsx) ||
|
||||||
|
SemaBuiltinConstantArgRange(TheCall, 1, 0, 127);
|
||||||
|
}
|
||||||
#define CUSTOM_BUILTIN(Name, Intr, Types, Acc) \
|
#define CUSTOM_BUILTIN(Name, Intr, Types, Acc) \
|
||||||
case PPC::BI__builtin_##Name: \
|
case PPC::BI__builtin_##Name: \
|
||||||
return SemaBuiltinPPCMMACall(TheCall, Types);
|
return SemaBuiltinPPCMMACall(TheCall, Types);
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
extern unsigned int ui;
|
extern unsigned int ui;
|
||||||
extern unsigned long long ull;
|
extern unsigned long long ull;
|
||||||
extern long long ll;
|
extern long long ll;
|
||||||
|
extern float f;
|
||||||
|
extern double d;
|
||||||
|
|
||||||
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]}}
|
||||||
|
@ -24,3 +26,23 @@ void test_builtin_ppc_addex() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
int test_builtin_ppc_test_data_class_d() {
|
||||||
|
return __builtin_ppc_test_data_class(d, -1); // expected-error {{argument value -1 is outside the valid range [0, 127]}}
|
||||||
|
}
|
||||||
|
|
||||||
|
int test_builtin_ppc_test_data_class_f() {
|
||||||
|
return __builtin_ppc_test_data_class(f, -1); // expected-error {{argument value -1 is outside the valid range [0, 127]}}
|
||||||
|
}
|
||||||
|
|
||||||
|
int test_test_data_class_d() {
|
||||||
|
return __test_data_class(d, 128); // expected-error {{argument value 128 is outside the valid range [0, 127]}}
|
||||||
|
}
|
||||||
|
|
||||||
|
int test_test_data_class_f() {
|
||||||
|
return __test_data_class(f, 128); // expected-error {{argument value 128 is outside the valid range [0, 127]}}
|
||||||
|
}
|
||||||
|
|
||||||
|
int test_test_data_class_type() {
|
||||||
|
return __test_data_class(ui, 0); // expected-error {{expected a 'float' or 'double' for the first argument}}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,124 @@
|
||||||
|
// REQUIRES: powerpc-registered-target
|
||||||
|
// RUN: %clang_cc1 -triple powerpc64-unknown-unknown -emit-llvm %s \
|
||||||
|
// RUN: -target-cpu pwr9 -o - | FileCheck %s
|
||||||
|
// RUN: %clang_cc1 -triple powerpc64le-unknown-unknown -emit-llvm %s \
|
||||||
|
// RUN: -target-cpu pwr9 -o - | FileCheck %s
|
||||||
|
// RUN: %clang_cc1 -triple powerpc64-unknown-aix -emit-llvm %s \
|
||||||
|
// RUN: -target-cpu pwr9 -o - | FileCheck %s
|
||||||
|
// RUN: %clang_cc1 -triple powerpc-unknown-aix %s -emit-llvm %s \
|
||||||
|
// RUN: -target-cpu pwr9 -o - | FileCheck %s
|
||||||
|
// RUN: not %clang_cc1 -triple powerpc64-unknown-unknown -emit-llvm-only %s \
|
||||||
|
// RUN: -target-cpu pwr8 2>&1 | FileCheck %s --check-prefix=CHECK-NONPWR9-ERR
|
||||||
|
// RUN: not %clang_cc1 -target-feature -vsx -triple powerpc64-unknown-unknown -emit-llvm-only %s \
|
||||||
|
// RUN: -target-cpu pwr9 2>&1 | FileCheck %s --check-prefix=CHECK-NOVSX-ERR
|
||||||
|
|
||||||
|
extern double d;
|
||||||
|
extern float f;
|
||||||
|
|
||||||
|
int test_builtin_ppc_compare_exp_uo() {
|
||||||
|
// CHECK-LABEL: @test_builtin_ppc_compare_exp_uo
|
||||||
|
// CHECK: [[TMP:%.*]] = call i32 @llvm.ppc.compare.exp.uo(double %0, double %1)
|
||||||
|
// CHECK-NEXT: ret i32 [[TMP]]
|
||||||
|
// CHECK-NONPWR9-ERR: error: this builtin is only valid on POWER9 or later CPUs
|
||||||
|
// CHECK-NOVSX-ERR: error: this builtin requires VSX to be enabled
|
||||||
|
return __builtin_ppc_compare_exp_uo(d, d);
|
||||||
|
}
|
||||||
|
|
||||||
|
int test_builtin_ppc_compare_exp_lt() {
|
||||||
|
// CHECK-LABEL: @test_builtin_ppc_compare_exp_lt
|
||||||
|
// CHECK: [[TMP:%.*]] = call i32 @llvm.ppc.compare.exp.lt(double %0, double %1)
|
||||||
|
// CHECK-NEXT: ret i32 [[TMP]]
|
||||||
|
// CHECK-NONPWR9-ERR: error: this builtin is only valid on POWER9 or later CPUs
|
||||||
|
// CHECK-NOVSX-ERR: error: this builtin requires VSX to be enabled
|
||||||
|
return __builtin_ppc_compare_exp_lt(d, d);
|
||||||
|
}
|
||||||
|
|
||||||
|
int test_builtin_ppc_compare_exp_gt() {
|
||||||
|
// CHECK-LABEL: @test_builtin_ppc_compare_exp_gt
|
||||||
|
// CHECK: [[TMP:%.*]] = call i32 @llvm.ppc.compare.exp.gt(double %0, double %1)
|
||||||
|
// CHECK-NEXT: ret i32 [[TMP]]
|
||||||
|
// CHECK-NONPWR9-ERR: error: this builtin is only valid on POWER9 or later CPUs
|
||||||
|
// CHECK-NOVSX-ERR: error: this builtin requires VSX to be enabled
|
||||||
|
return __builtin_ppc_compare_exp_gt(d, d);
|
||||||
|
}
|
||||||
|
|
||||||
|
int test_builtin_ppc_compare_exp_eq() {
|
||||||
|
// CHECK-LABEL: @test_builtin_ppc_compare_exp_eq
|
||||||
|
// CHECK: [[TMP:%.*]] = call i32 @llvm.ppc.compare.exp.eq(double %0, double %1)
|
||||||
|
// CHECK-NEXT: ret i32 [[TMP]]
|
||||||
|
// CHECK-NONPWR9-ERR: error: this builtin is only valid on POWER9 or later CPUs
|
||||||
|
// CHECK-NOVSX-ERR: error: this builtin requires VSX to be enabled
|
||||||
|
return __builtin_ppc_compare_exp_eq(d, d);
|
||||||
|
}
|
||||||
|
|
||||||
|
int test_builtin_ppc_test_data_class_d() {
|
||||||
|
// CHECK-LABEL: @test_builtin_ppc_test_data_class_d
|
||||||
|
// CHECK: [[TMP:%.*]] = call i32 @llvm.ppc.test.data.class.d(double %0, i32 0)
|
||||||
|
// CHECK-NEXT: ret i32 [[TMP]]
|
||||||
|
// CHECK-NONPWR9-ERR: error: this builtin is only valid on POWER9 or later CPUs
|
||||||
|
// CHECK-NOVSX-ERR: error: this builtin requires VSX to be enabled
|
||||||
|
return __builtin_ppc_test_data_class(d, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int test_builtin_ppc_test_data_class_f() {
|
||||||
|
// CHECK-LABEL: @test_builtin_ppc_test_data_class_f
|
||||||
|
// CHECK: [[TMP:%.*]] = call i32 @llvm.ppc.test.data.class.f(float %0, i32 0)
|
||||||
|
// CHECK-NEXT: ret i32 [[TMP]]
|
||||||
|
// CHECK-NONPWR9-ERR: error: this builtin is only valid on POWER9 or later CPUs
|
||||||
|
// CHECK-NOVSX-ERR: error: this builtin requires VSX to be enabled
|
||||||
|
return __builtin_ppc_test_data_class(f, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int test_compare_exp_uo() {
|
||||||
|
// CHECK-LABEL: @test_compare_exp_uo
|
||||||
|
// CHECK: [[TMP:%.*]] = call i32 @llvm.ppc.compare.exp.uo(double %0, double %1)
|
||||||
|
// CHECK-NEXT: ret i32 [[TMP]]
|
||||||
|
// CHECK-NONPWR9-ERR: error: this builtin is only valid on POWER9 or later CPUs
|
||||||
|
// CHECK-NOVSX-ERR: error: this builtin requires VSX to be enabled
|
||||||
|
return __compare_exp_uo(d, d);
|
||||||
|
}
|
||||||
|
|
||||||
|
int test_compare_exp_lt() {
|
||||||
|
// CHECK-LABEL: @test_compare_exp_lt
|
||||||
|
// CHECK: [[TMP:%.*]] = call i32 @llvm.ppc.compare.exp.lt(double %0, double %1)
|
||||||
|
// CHECK-NEXT: ret i32 [[TMP]]
|
||||||
|
// CHECK-NONPWR9-ERR: error: this builtin is only valid on POWER9 or later CPUs
|
||||||
|
// CHECK-NOVSX-ERR: error: this builtin requires VSX to be enabled
|
||||||
|
return __compare_exp_lt(d, d);
|
||||||
|
}
|
||||||
|
|
||||||
|
int test_compare_exp_gt() {
|
||||||
|
// CHECK-LABEL: @test_compare_exp_gt
|
||||||
|
// CHECK: [[TMP:%.*]] = call i32 @llvm.ppc.compare.exp.gt(double %0, double %1)
|
||||||
|
// CHECK-NEXT: ret i32 [[TMP]]
|
||||||
|
// CHECK-NONPWR9-ERR: error: this builtin is only valid on POWER9 or later CPUs
|
||||||
|
// CHECK-NOVSX-ERR: error: this builtin requires VSX to be enabled
|
||||||
|
return __compare_exp_gt(d, d);
|
||||||
|
}
|
||||||
|
|
||||||
|
int test_compare_exp_eq() {
|
||||||
|
// CHECK-LABEL: @test_compare_exp_eq
|
||||||
|
// CHECK: [[TMP:%.*]] = call i32 @llvm.ppc.compare.exp.eq(double %0, double %1)
|
||||||
|
// CHECK-NEXT: ret i32 [[TMP]]
|
||||||
|
// CHECK-NONPWR9-ERR: error: this builtin is only valid on POWER9 or later CPUs
|
||||||
|
// CHECK-NOVSX-ERR: error: this builtin requires VSX to be enabled
|
||||||
|
return __compare_exp_eq(d, d);
|
||||||
|
}
|
||||||
|
|
||||||
|
int test_test_data_class_d() {
|
||||||
|
// CHECK-LABEL: @test_test_data_class_d
|
||||||
|
// CHECK: [[TMP:%.*]] = call i32 @llvm.ppc.test.data.class.d(double %0, i32 127)
|
||||||
|
// CHECK-NEXT: ret i32 [[TMP]]
|
||||||
|
// CHECK-NONPWR9-ERR: error: this builtin is only valid on POWER9 or later CPUs
|
||||||
|
// CHECK-NOVSX-ERR: error: this builtin requires VSX to be enabled
|
||||||
|
return __test_data_class(d, 127);
|
||||||
|
}
|
||||||
|
|
||||||
|
int test_test_data_class_f() {
|
||||||
|
// CHECK-LABEL: @test_test_data_class_f
|
||||||
|
// CHECK: [[TMP:%.*]] = call i32 @llvm.ppc.test.data.class.f(float %0, i32 127)
|
||||||
|
// CHECK-NEXT: ret i32 [[TMP]]
|
||||||
|
// CHECK-NONPWR9-ERR: error: this builtin is only valid on POWER9 or later CPUs
|
||||||
|
// CHECK-NOVSX-ERR: error: this builtin requires VSX to be enabled
|
||||||
|
return __test_data_class(f, 127);
|
||||||
|
}
|
|
@ -1720,6 +1720,28 @@ let TargetPrefix = "ppc" in {
|
||||||
Intrinsic<[llvm_double_ty], [llvm_double_ty], [IntrNoMem]>;
|
Intrinsic<[llvm_double_ty], [llvm_double_ty], [IntrNoMem]>;
|
||||||
def int_ppc_frsqrtes : GCCBuiltin<"__builtin_ppc_frsqrtes">,
|
def int_ppc_frsqrtes : GCCBuiltin<"__builtin_ppc_frsqrtes">,
|
||||||
Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
|
Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
|
||||||
|
def int_ppc_compare_exp_uo : GCCBuiltin<"__builtin_ppc_compare_exp_uo">,
|
||||||
|
Intrinsic<[llvm_i32_ty],
|
||||||
|
[llvm_double_ty, llvm_double_ty],
|
||||||
|
[IntrNoMem]>;
|
||||||
|
def int_ppc_compare_exp_lt : GCCBuiltin<"__builtin_ppc_compare_exp_lt">,
|
||||||
|
Intrinsic<[llvm_i32_ty],
|
||||||
|
[llvm_double_ty, llvm_double_ty],
|
||||||
|
[IntrNoMem]>;
|
||||||
|
def int_ppc_compare_exp_gt : GCCBuiltin<"__builtin_ppc_compare_exp_gt">,
|
||||||
|
Intrinsic<[llvm_i32_ty],
|
||||||
|
[llvm_double_ty, llvm_double_ty],
|
||||||
|
[IntrNoMem]>;
|
||||||
|
def int_ppc_compare_exp_eq : GCCBuiltin<"__builtin_ppc_compare_exp_eq">,
|
||||||
|
Intrinsic<[llvm_i32_ty],
|
||||||
|
[llvm_double_ty, llvm_double_ty],
|
||||||
|
[IntrNoMem]>;
|
||||||
|
def int_ppc_test_data_class_d : Intrinsic<[llvm_i32_ty],
|
||||||
|
[llvm_double_ty, llvm_i32_ty],
|
||||||
|
[IntrNoMem, ImmArg<ArgIndex<1>>]>;
|
||||||
|
def int_ppc_test_data_class_f : Intrinsic<[llvm_i32_ty],
|
||||||
|
[llvm_float_ty, llvm_i32_ty],
|
||||||
|
[IntrNoMem, ImmArg<ArgIndex<1>>]>;
|
||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
|
@ -10373,6 +10373,50 @@ SDValue PPCTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
|
||||||
}
|
}
|
||||||
return DAG.getMergeValues(RetOps, dl);
|
return DAG.getMergeValues(RetOps, dl);
|
||||||
}
|
}
|
||||||
|
case Intrinsic::ppc_compare_exp_lt:
|
||||||
|
case Intrinsic::ppc_compare_exp_gt:
|
||||||
|
case Intrinsic::ppc_compare_exp_eq:
|
||||||
|
case Intrinsic::ppc_compare_exp_uo: {
|
||||||
|
unsigned Pred;
|
||||||
|
switch (IntrinsicID) {
|
||||||
|
case Intrinsic::ppc_compare_exp_lt:
|
||||||
|
Pred = PPC::PRED_LT;
|
||||||
|
break;
|
||||||
|
case Intrinsic::ppc_compare_exp_gt:
|
||||||
|
Pred = PPC::PRED_GT;
|
||||||
|
break;
|
||||||
|
case Intrinsic::ppc_compare_exp_eq:
|
||||||
|
Pred = PPC::PRED_EQ;
|
||||||
|
break;
|
||||||
|
case Intrinsic::ppc_compare_exp_uo:
|
||||||
|
Pred = PPC::PRED_UN;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return SDValue(
|
||||||
|
DAG.getMachineNode(
|
||||||
|
PPC::SELECT_CC_I4, dl, MVT::i32,
|
||||||
|
{SDValue(DAG.getMachineNode(PPC::XSCMPEXPDP, dl, MVT::i32,
|
||||||
|
Op.getOperand(1), Op.getOperand(2)),
|
||||||
|
0),
|
||||||
|
DAG.getConstant(1, dl, MVT::i32), DAG.getConstant(0, dl, MVT::i32),
|
||||||
|
DAG.getTargetConstant(Pred, dl, MVT::i32)}),
|
||||||
|
0);
|
||||||
|
}
|
||||||
|
case Intrinsic::ppc_test_data_class_d:
|
||||||
|
case Intrinsic::ppc_test_data_class_f: {
|
||||||
|
unsigned CmprOpc = PPC::XSTSTDCDP;
|
||||||
|
if (IntrinsicID == Intrinsic::ppc_test_data_class_f)
|
||||||
|
CmprOpc = PPC::XSTSTDCSP;
|
||||||
|
return SDValue(
|
||||||
|
DAG.getMachineNode(
|
||||||
|
PPC::SELECT_CC_I4, dl, MVT::i32,
|
||||||
|
{SDValue(DAG.getMachineNode(CmprOpc, dl, MVT::i32, Op.getOperand(2),
|
||||||
|
Op.getOperand(1)),
|
||||||
|
0),
|
||||||
|
DAG.getConstant(1, dl, MVT::i32), DAG.getConstant(0, dl, MVT::i32),
|
||||||
|
DAG.getTargetConstant(PPC::PRED_EQ, dl, MVT::i32)}),
|
||||||
|
0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this is a lowered altivec predicate compare, CompareOpc is set to the
|
// If this is a lowered altivec predicate compare, CompareOpc is set to the
|
||||||
|
|
|
@ -0,0 +1,99 @@
|
||||||
|
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||||
|
; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-unknown \
|
||||||
|
; RUN: -mcpu=pwr9 < %s | FileCheck %s
|
||||||
|
; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-unknown \
|
||||||
|
; RUN: -mcpu=pwr9 < %s | FileCheck %s
|
||||||
|
; RUN: llc -verify-machineinstrs -mtriple=powerpc-unknown-aix \
|
||||||
|
; RUN: -mcpu=pwr9 < %s | FileCheck %s
|
||||||
|
; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-aix \
|
||||||
|
; RUN: -mcpu=pwr9 < %s | FileCheck %s
|
||||||
|
|
||||||
|
define i32 @test_builtin_ppc_compare_exp_eq(double %d) {
|
||||||
|
; CHECK-LABEL: test_builtin_ppc_compare_exp_eq:
|
||||||
|
; CHECK: # %bb.0: # %entry
|
||||||
|
; CHECK-NEXT: xscmpexpdp 0, 1, 1
|
||||||
|
; CHECK-NEXT: li 3, 0
|
||||||
|
; CHECK-NEXT: li 4, 1
|
||||||
|
; CHECK-NEXT: iseleq 3, 4, 3
|
||||||
|
; CHECK-NEXT: blr
|
||||||
|
entry:
|
||||||
|
%0 = tail call i32 @llvm.ppc.compare.exp.eq(double %d, double %d)
|
||||||
|
ret i32 %0
|
||||||
|
}
|
||||||
|
|
||||||
|
declare i32 @llvm.ppc.compare.exp.eq(double, double)
|
||||||
|
|
||||||
|
define i32 @test_builtin_ppc_compare_exp_lt(double %d) {
|
||||||
|
; CHECK-LABEL: test_builtin_ppc_compare_exp_lt:
|
||||||
|
; CHECK: # %bb.0: # %entry
|
||||||
|
; CHECK-NEXT: xscmpexpdp 0, 1, 1
|
||||||
|
; CHECK-NEXT: li 3, 0
|
||||||
|
; CHECK-NEXT: li 4, 1
|
||||||
|
; CHECK-NEXT: isellt 3, 4, 3
|
||||||
|
; CHECK-NEXT: blr
|
||||||
|
entry:
|
||||||
|
%0 = tail call i32 @llvm.ppc.compare.exp.lt(double %d, double %d)
|
||||||
|
ret i32 %0
|
||||||
|
}
|
||||||
|
|
||||||
|
declare i32 @llvm.ppc.compare.exp.lt(double, double)
|
||||||
|
|
||||||
|
define i32 @test_builtin_ppc_compare_exp_gt(double %d) {
|
||||||
|
; CHECK-LABEL: test_builtin_ppc_compare_exp_gt:
|
||||||
|
; CHECK: # %bb.0: # %entry
|
||||||
|
; CHECK-NEXT: xscmpexpdp 0, 1, 1
|
||||||
|
; CHECK-NEXT: li 3, 0
|
||||||
|
; CHECK-NEXT: li 4, 1
|
||||||
|
; CHECK-NEXT: iselgt 3, 4, 3
|
||||||
|
; CHECK-NEXT: blr
|
||||||
|
entry:
|
||||||
|
%0 = tail call i32 @llvm.ppc.compare.exp.gt(double %d, double %d)
|
||||||
|
ret i32 %0
|
||||||
|
}
|
||||||
|
|
||||||
|
declare i32 @llvm.ppc.compare.exp.gt(double, double)
|
||||||
|
|
||||||
|
define i32 @test_builtin_ppc_compare_exp_uo(double %d) {
|
||||||
|
; CHECK-LABEL: test_builtin_ppc_compare_exp_uo:
|
||||||
|
; CHECK: # %bb.0: # %entry
|
||||||
|
; CHECK-NEXT: xscmpexpdp 0, 1, 1
|
||||||
|
; CHECK-NEXT: li 3, 0
|
||||||
|
; CHECK-NEXT: li 4, 1
|
||||||
|
; CHECK-NEXT: isel 3, 4, 3, 3
|
||||||
|
; CHECK-NEXT: blr
|
||||||
|
entry:
|
||||||
|
%0 = tail call i32 @llvm.ppc.compare.exp.uo(double %d, double %d)
|
||||||
|
ret i32 %0
|
||||||
|
}
|
||||||
|
|
||||||
|
declare i32 @llvm.ppc.compare.exp.uo(double, double)
|
||||||
|
|
||||||
|
define i32 @test_builtin_ppc_test_data_class_d(double %d) {
|
||||||
|
; CHECK-LABEL: test_builtin_ppc_test_data_class_d:
|
||||||
|
; CHECK: # %bb.0: # %entry
|
||||||
|
; CHECK-NEXT: xststdcdp 0, 1, 0
|
||||||
|
; CHECK-NEXT: li 3, 0
|
||||||
|
; CHECK-NEXT: li 4, 1
|
||||||
|
; CHECK-NEXT: iseleq 3, 4, 3
|
||||||
|
; CHECK-NEXT: blr
|
||||||
|
entry:
|
||||||
|
%test_data_class = tail call i32 @llvm.ppc.test.data.class.d(double %d, i32 0)
|
||||||
|
ret i32 %test_data_class
|
||||||
|
}
|
||||||
|
|
||||||
|
declare i32 @llvm.ppc.test.data.class.d(double, i32 immarg)
|
||||||
|
|
||||||
|
define i32 @test_builtin_ppc_test_data_class_f(float %f) {
|
||||||
|
; CHECK-LABEL: test_builtin_ppc_test_data_class_f:
|
||||||
|
; CHECK: # %bb.0: # %entry
|
||||||
|
; CHECK-NEXT: xststdcsp 0, 1, 127
|
||||||
|
; CHECK-NEXT: li 3, 0
|
||||||
|
; CHECK-NEXT: li 4, 1
|
||||||
|
; CHECK-NEXT: iseleq 3, 4, 3
|
||||||
|
; CHECK-NEXT: blr
|
||||||
|
entry:
|
||||||
|
%test_data_class = tail call i32 @llvm.ppc.test.data.class.f(float %f, i32 127)
|
||||||
|
ret i32 %test_data_class
|
||||||
|
}
|
||||||
|
|
||||||
|
declare i32 @llvm.ppc.test.data.class.f(float, i32 immarg)
|
Loading…
Reference in New Issue