Skip to content

Commit

Permalink
[PowerPC] Implement trap and conversion builtins for XL compatibility
Browse files Browse the repository at this point in the history
This patch implements trap and FP to and from double conversions. The builtins
generate code that mirror what is generated from the XL compiler. Intrinsics
are named conventionally with builtin_ppc, but are aliased to provide the same
builtin names as the XL compiler.

Differential Revision: https://reviews.llvm.org/D103668
  • Loading branch information
Conanap committed Jul 8, 2021
1 parent 6a06dba commit 004c12b
Show file tree
Hide file tree
Showing 13 changed files with 676 additions and 1 deletion.
12 changes: 12 additions & 0 deletions clang/include/clang/Basic/BuiltinsPPC.def
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,18 @@ BUILTIN(__builtin_ppc_ldarx, "LiLiD*", "")
BUILTIN(__builtin_ppc_lwarx, "iiD*", "")
BUILTIN(__builtin_ppc_stdcx, "iLiD*Li", "")
BUILTIN(__builtin_ppc_stwcx, "iiD*i", "")
BUILTIN(__builtin_ppc_tdw, "vLLiLLiIUi", "")
BUILTIN(__builtin_ppc_tw, "viiIUi", "")
BUILTIN(__builtin_ppc_trap, "vi", "")
BUILTIN(__builtin_ppc_trapd, "vLi", "")
BUILTIN(__builtin_ppc_fcfid, "dd", "")
BUILTIN(__builtin_ppc_fcfud, "dd", "")
BUILTIN(__builtin_ppc_fctid, "dd", "")
BUILTIN(__builtin_ppc_fctidz, "dd", "")
BUILTIN(__builtin_ppc_fctiw, "dd", "")
BUILTIN(__builtin_ppc_fctiwz, "dd", "")
BUILTIN(__builtin_ppc_fctudz, "dd", "")
BUILTIN(__builtin_ppc_fctuwz, "dd", "")

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

Expand Down
12 changes: 12 additions & 0 deletions clang/lib/Basic/Targets/PPC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,18 @@ static void defineXLCompatMacros(MacroBuilder &Builder) {
Builder.defineMacro("__lwarx", "__builtin_ppc_lwarx");
Builder.defineMacro("__stdcx", "__builtin_ppc_stdcx");
Builder.defineMacro("__stwcx", "__builtin_ppc_stwcx");
Builder.defineMacro("__tdw", "__builtin_ppc_tdw");
Builder.defineMacro("__tw", "__builtin_ppc_tw");
Builder.defineMacro("__trap", "__builtin_ppc_trap");
Builder.defineMacro("__trapd", "__builtin_ppc_trapd");
Builder.defineMacro("__fcfid", "__builtin_ppc_fcfid");
Builder.defineMacro("__fcfud", "__builtin_ppc_fcfud");
Builder.defineMacro("__fctid", "__builtin_ppc_fctid");
Builder.defineMacro("__fctidz", "__builtin_ppc_fctidz");
Builder.defineMacro("__fctiw", "__builtin_ppc_fctiw");
Builder.defineMacro("__fctiwz", "__builtin_ppc_fctiwz");
Builder.defineMacro("__fctudz", "__builtin_ppc_fctudz");
Builder.defineMacro("__fctuwz", "__builtin_ppc_fctuwz");
}

/// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific
Expand Down
5 changes: 5 additions & 0 deletions clang/lib/Sema/SemaChecking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3267,6 +3267,8 @@ static bool isPPC_64Builtin(unsigned BuiltinID) {
case PPC::BI__builtin_bpermd:
case PPC::BI__builtin_ppc_ldarx:
case PPC::BI__builtin_ppc_stdcx:
case PPC::BI__builtin_ppc_tdw:
case PPC::BI__builtin_ppc_trapd:
return true;
}
return false;
Expand Down Expand Up @@ -3347,6 +3349,9 @@ bool Sema::CheckPPCBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID,
return SemaBuiltinConstantArgRange(TheCall, 2, 0, 7);
case PPC::BI__builtin_vsx_xxpermx:
return SemaBuiltinConstantArgRange(TheCall, 3, 0, 7);
case PPC::BI__builtin_ppc_tw:
case PPC::BI__builtin_ppc_tdw:
return SemaBuiltinConstantArgRange(TheCall, 2, 0, 31);
#define CUSTOM_BUILTIN(Name, Intr, Types, Acc) \
case PPC::BI__builtin_##Name: \
return SemaBuiltinPPCMMACall(TheCall, Types);
Expand Down
121 changes: 121 additions & 0 deletions clang/test/CodeGen/builtins-ppc-xlcompat-conversionfunc.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
// RUN: %clang_cc1 -O2 -triple powerpc64-unknown-unknown \
// RUN: -emit-llvm %s -o - -target-cpu pwr7 | FileCheck %s
// RUN: %clang_cc1 -O2 -triple powerpc64le-unknown-unknown \
// RUN: -emit-llvm %s -o - -target-cpu pwr8 | FileCheck %s
// RUN: %clang_cc1 -O2 -triple powerpc-unknown-aix \
// RUN: -emit-llvm %s -o - -target-cpu pwr7 | FileCheck %s
// RUN: %clang_cc1 -O2 -triple powerpc64-unknown-aix \
// RUN: -emit-llvm %s -o - -target-cpu pwr7 | FileCheck %s

extern double da;
double test_fcfid() {
// CHECK-LABEL: test_fcfid
// CHECK-NEXT: entry:
// CHECK: double @llvm.ppc.fcfid(double %0)
return __builtin_ppc_fcfid(da);
}

double test_xl_fcfid() {
// CHECK-LABEL: test_xl_fcfid
// CHECK-NEXT: entry:
// CHECK: double @llvm.ppc.fcfid(double %0)
return __fcfid(da);
}

double test_fcfud() {
// CHECK-LABEL: test_fcfud
// CHECK-NEXT: entry:
// CHECK: double @llvm.ppc.fcfud(double %0)
return __builtin_ppc_fcfud(da);
}

double test_xl_fcfud() {
// CHECK-LABEL: test_xl_fcfud
// CHECK-NEXT: entry:
// CHECK: double @llvm.ppc.fcfud(double %0)
return __fcfud(da);
}

double test_fctid() {
// CHECK-LABEL: test_fctid
// CHECK-NEXT: entry:
// CHECK: double @llvm.ppc.fctid(double %0)
return __builtin_ppc_fctid(da);
}

double test_xl_fctid() {
// CHECK-LABEL: test_xl_fctid
// CHECK-NEXT: entry:
// CHECK: double @llvm.ppc.fctid(double %0)
return __fctid(da);
}

double test_fctidz() {
// CHECK-LABEL: test_fctidz
// CHECK-NEXT: entry:
// CHECK: double @llvm.ppc.fctidz(double %0)
return __builtin_ppc_fctidz(da);
}

double test_xl_fctidz() {
// CHECK-LABEL: test_xl_fctidz
// CHECK-NEXT: entry:
// CHECK: double @llvm.ppc.fctidz(double %0)
return __fctidz(da);
}

double test_fctiw() {
// CHECK-LABEL: test_fctiw
// CHECK-NEXT: entry:
// CHECK: double @llvm.ppc.fctiw(double %0)
return __builtin_ppc_fctiw(da);
}

double test_xl_fctiw() {
// CHECK-LABEL: test_xl_fctiw
// CHECK-NEXT: entry:
// CHECK: double @llvm.ppc.fctiw(double %0)
return __fctiw(da);
}

double test_fctiwz() {
// CHECK-LABEL: test_fctiwz
// CHECK-NEXT: entry:
// CHECK: double @llvm.ppc.fctiwz(double %0)
return __builtin_ppc_fctiwz(da);
}

double test_xl_fctiwz() {
// CHECK-LABEL: test_xl_fctiwz
// CHECK-NEXT: entry:
// CHECK: double @llvm.ppc.fctiwz(double %0)
return __fctiwz(da);
}

double test_fctudz() {
// CHECK-LABEL: test_fctudz
// CHECK-NEXT: entry:
// CHECK: double @llvm.ppc.fctudz(double %0)
return __builtin_ppc_fctudz(da);
}

double test_xl_fctudz() {
// CHECK-LABEL: test_xl_fctudz
// CHECK-NEXT: entry:
// CHECK: double @llvm.ppc.fctudz(double %0)
return __fctudz(da);
}

double test_fctuwz() {
// CHECK-LABEL: test_fctuwz
// CHECK-NEXT: entry:
// CHECK: double @llvm.ppc.fctuwz(double %0)
return __builtin_ppc_fctuwz(da);
}

double test_xl_fctuwz() {
// CHECK-LABEL: test_xl_fctuwz
// CHECK-NEXT: entry:
// CHECK: double @llvm.ppc.fctuwz(double %0)
return __fctuwz(da);
}
19 changes: 19 additions & 0 deletions clang/test/CodeGen/builtins-ppc-xlcompat-error.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// REQUIRES: powerpc-registered-target
// RUN: %clang_cc1 -triple powerpc64-unknown-unknown -fsyntax-only \
// RUN: -Wall -Werror -verify %s
// RUN: %clang_cc1 -triple powerpc64le-unknown-unknown -fsyntax-only \
// RUN: -Wall -Werror -verify %s
// RUN: %clang_cc1 -triple powerpc64-unknown-aix -fsyntax-only \
// RUN: -Wall -Werror -verify %s
// RUN: %clang_cc1 -triple powerpc-unknown-aix -fsyntax-only \
// RUN: -Wall -Werror -verify %s

extern long long lla, llb;
extern int ia, ib;

void test_trap(void) {
#ifdef __PPC64__
__tdw(lla, llb, 50); //expected-error {{argument value 50 is outside the valid range [0, 31]}}
#endif
__tw(ia, ib, 50); //expected-error {{argument value 50 is outside the valid range [0, 31]}}
}
41 changes: 41 additions & 0 deletions clang/test/CodeGen/builtins-ppc-xlcompat-trap-64bit-only.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// RUN: %clang_cc1 -O2 -triple powerpc64-unknown-unknown \
// RUN: -emit-llvm %s -o - -target-cpu pwr7 | \
// RUN: FileCheck %s --check-prefixes=CHECK64
// RUN: %clang_cc1 -O2 -triple powerpc64le-unknown-unknown \
// RUN: -emit-llvm %s -o - -target-cpu pwr8 | \
// RUN: FileCheck %s --check-prefixes=CHECK64
// RUN: not %clang_cc1 -O2 -triple powerpc-unknown-aix \
// RUN: -emit-llvm %s -o - -target-cpu pwr7 2>&1 | \
// RUN: FileCheck %s -check-prefixes=CHECK32-ERROR
// RUN: %clang_cc1 -O2 -triple powerpc64-unknown-aix \
// RUN: -emit-llvm %s -o - -target-cpu pwr7 | \
// RUN: FileCheck %s --check-prefixes=CHECK64

extern long long lla, llb;
extern double da;

// tdw
void test_xl_tdw(void) {
// CHECK64: void @llvm.ppc.tdw(i64 %0, i64 %1, i32 1)
// CHECK32-ERROR: error: this builtin is only available on 64-bit targets
__tdw(lla, llb, 1);
}

void test_tdw(void) {
// CHECK64: void @llvm.ppc.tdw(i64 %0, i64 %1, i32 13)
// CHECK32-ERROR: error: this builtin is only available on 64-bit targets
__builtin_ppc_tdw(lla, llb, 13);
}

// trapd
void test_trapd(void) {
// CHECK64: void @llvm.ppc.trapd(i64 %conv)
// CHECK32-ERROR: error: this builtin is only available on 64-bit targets
__builtin_ppc_trapd(da);
}

void test_xl_trapd(void) {
// CHECK64: void @llvm.ppc.trapd(i64 %conv)
// CHECK32-ERROR: error: this builtin is only available on 64-bit targets
__trapd(da);
}
38 changes: 38 additions & 0 deletions clang/test/CodeGen/builtins-ppc-xlcompat-trap.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// RUN: %clang_cc1 -O2 -triple powerpc64-unknown-unknown \
// RUN: -emit-llvm %s -o - -target-cpu pwr7 | \
// RUN: FileCheck %s
// RUN: %clang_cc1 -O2 -triple powerpc64le-unknown-unknown \
// RUN: -emit-llvm %s -o - -target-cpu pwr8 | \
// RUN: FileCheck %s
// RUN: %clang_cc1 -O2 -triple powerpc-unknown-aix \
// RUN: -emit-llvm %s -o - -target-cpu pwr7 | \
// RUN: FileCheck %s
// RUN: %clang_cc1 -O2 -triple powerpc64-unknown-aix \
// RUN: -emit-llvm %s -o - -target-cpu pwr7 | \
// RUN: FileCheck %s

extern int ia, ib;

// td
void test_tw(void) {
// CHECK: void @llvm.ppc.tw(i32 %0, i32 %1, i32 1)

__builtin_ppc_tw(ia, ib, 1);
}

void test_xl_tw(void) {
// CHECK: void @llvm.ppc.tw(i32 %0, i32 %1, i32 1)

__tw(ia, ib, 1);
}

// trap
void test_trap(void) {
// CHECK: void @llvm.ppc.trap(i32 %0)
__builtin_ppc_trap(ia);
}

void test_xl_trap(void) {
// CHECK: void @llvm.ppc.trap(i32 %0)
__trap(ia);
}
38 changes: 37 additions & 1 deletion llvm/include/llvm/IR/IntrinsicsPowerPC.td
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,45 @@ let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.".
: GCCBuiltin<"__builtin_vsx_scalar_insert_exp_qp">,
Intrinsic <[llvm_f128_ty], [llvm_f128_ty, llvm_i64_ty], [IntrNoMem]>;

// Intrinsics defined to maintain XL compatibility
def int_ppc_tdw
: GCCBuiltin<"__builtin_ppc_tdw">,
Intrinsic <[], [llvm_i64_ty, llvm_i64_ty, llvm_i32_ty], [ImmArg<ArgIndex<2>>]>;
def int_ppc_tw
: GCCBuiltin<"__builtin_ppc_tw">,
Intrinsic <[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [ImmArg<ArgIndex<2>>]>;
def int_ppc_trapd
: GCCBuiltin<"__builtin_ppc_trapd">,
Intrinsic <[], [llvm_i64_ty], []>;
def int_ppc_trap
: GCCBuiltin<"__builtin_ppc_trap">,
Intrinsic <[], [llvm_i32_ty], []>;
def int_ppc_fcfid
: GCCBuiltin<"__builtin_ppc_fcfid">,
Intrinsic <[llvm_double_ty], [llvm_double_ty], [IntrNoMem]>;
def int_ppc_fcfud
: GCCBuiltin<"__builtin_ppc_fcfud">,
Intrinsic <[llvm_double_ty], [llvm_double_ty], [IntrNoMem]>;
def int_ppc_fctid
: GCCBuiltin<"__builtin_ppc_fctid">,
Intrinsic <[llvm_double_ty], [llvm_double_ty], [IntrNoMem]>;
def int_ppc_fctidz
: GCCBuiltin<"__builtin_ppc_fctidz">,
Intrinsic <[llvm_double_ty], [llvm_double_ty], [IntrNoMem]>;
def int_ppc_fctiw
: GCCBuiltin<"__builtin_ppc_fctiw">,
Intrinsic <[llvm_double_ty], [llvm_double_ty], [IntrNoMem]>;
def int_ppc_fctiwz
: GCCBuiltin<"__builtin_ppc_fctiwz">,
Intrinsic <[llvm_double_ty], [llvm_double_ty], [IntrNoMem]>;
def int_ppc_fctudz
: GCCBuiltin<"__builtin_ppc_fctudz">,
Intrinsic <[llvm_double_ty], [llvm_double_ty], [IntrNoMem]>;
def int_ppc_fctuwz
: GCCBuiltin<"__builtin_ppc_fctuwz">,
Intrinsic <[llvm_double_ty], [llvm_double_ty], [IntrNoMem]>;
}


let TargetPrefix = "ppc" in { // All PPC intrinsics start with "llvm.ppc.".
/// PowerPC_Vec_Intrinsic - Base class for all altivec intrinsics.
class PowerPC_Vec_Intrinsic<string GCCIntSuffix, list<LLVMType> ret_types,
Expand Down
6 changes: 6 additions & 0 deletions llvm/lib/Target/PowerPC/PPCInstr64Bit.td
Original file line number Diff line number Diff line change
Expand Up @@ -1725,3 +1725,9 @@ def : Pat<(int_ppc_stdcx ForceXForm:$dst, g8rc:$A),
(STDCX g8rc:$A, ForceXForm:$dst)>;
def : Pat<(int_ppc_ldarx ForceXForm:$dst),
(LDARX ForceXForm:$dst)>;
def : Pat<(int_ppc_tdw g8rc:$A, g8rc:$B, i32:$IMM),
(TD $IMM, $A, $B)>;

// trapd
def : Pat<(int_ppc_trapd g8rc:$A),
(TDI 24, $A, 0)>;
21 changes: 21 additions & 0 deletions llvm/lib/Target/PowerPC/PPCInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -5416,3 +5416,24 @@ def : Pat<(int_ppc_lwarx ForceXForm:$dst),
(LWARX ForceXForm:$dst)>;
def : Pat<(int_ppc_stwcx ForceXForm:$dst, gprc:$A),
(STWCX gprc:$A, ForceXForm:$dst)>;
def : Pat<(int_ppc_tw gprc:$A, gprc:$B, i32:$IMM),
(TW $IMM, $A, $B)>;
def : Pat<(int_ppc_trap gprc:$A),
(TWI 24, $A, 0)>;

def : Pat<(int_ppc_fcfid f64:$A),
(XSCVSXDDP $A)>;
def : Pat<(int_ppc_fcfud f64:$A),
(XSCVUXDDP $A)>;
def : Pat<(int_ppc_fctid f64:$A),
(FCTID $A)>;
def : Pat<(int_ppc_fctidz f64:$A),
(XSCVDPSXDS $A)>;
def : Pat<(int_ppc_fctiw f64:$A),
(FCTIW $A)>;
def : Pat<(int_ppc_fctiwz f64:$A),
(XSCVDPSXWS $A)>;
def : Pat<(int_ppc_fctudz f64:$A),
(XSCVDPUXDS $A)>;
def : Pat<(int_ppc_fctuwz f64:$A),
(XSCVDPUXWS $A)>;
Loading

0 comments on commit 004c12b

Please sign in to comment.