diff --git a/include/llvm/IR/IntrinsicsPowerPC.td b/include/llvm/IR/IntrinsicsPowerPC.td index ad6a1e8d1a7..c02d964e5dd 100644 --- a/include/llvm/IR/IntrinsicsPowerPC.td +++ b/include/llvm/IR/IntrinsicsPowerPC.td @@ -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>]>; + def int_ppc_tw + : GCCBuiltin<"__builtin_ppc_tw">, + Intrinsic <[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [ImmArg>]>; + 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 ret_types, diff --git a/lib/Target/PowerPC/PPCInstr64Bit.td b/lib/Target/PowerPC/PPCInstr64Bit.td index dc6a0c1a30e..aad6c5dd13b 100644 --- a/lib/Target/PowerPC/PPCInstr64Bit.td +++ b/lib/Target/PowerPC/PPCInstr64Bit.td @@ -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)>; diff --git a/lib/Target/PowerPC/PPCInstrInfo.td b/lib/Target/PowerPC/PPCInstrInfo.td index 20429ee664b..eea5c6de4be 100644 --- a/lib/Target/PowerPC/PPCInstrInfo.td +++ b/lib/Target/PowerPC/PPCInstrInfo.td @@ -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)>; diff --git a/test/CodeGen/PowerPC/builtins-ppc-xlcompat-conversionfunc.ll b/test/CodeGen/PowerPC/builtins-ppc-xlcompat-conversionfunc.ll new file mode 100644 index 00000000000..0bc1e17d5d6 --- /dev/null +++ b/test/CodeGen/PowerPC/builtins-ppc-xlcompat-conversionfunc.ll @@ -0,0 +1,89 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \ +; RUN: -mcpu=pwr8 < %s | FileCheck %s +; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu \ +; RUN: -mcpu=pwr7 < %s | FileCheck %s +; RUN: llc -verify-machineinstrs -mtriple=powerpc-unknown-aix \ +; RUN: -mcpu=pwr7 < %s | FileCheck %s +; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-aix \ +; RUN: -mcpu=pwr7 < %s | FileCheck %s + +declare double @llvm.ppc.fcfid(double %a) +define dso_local double @test_fcfid(double %a) { +; CHECK-LABEL: test_fcfid: +; CHECK: # %bb.0: +; CHECK-NEXT: xscvsxddp 1, 1 +; CHECK-NEXT: blr + %1 = call double @llvm.ppc.fcfid(double %a) + ret double %1 +} + +declare double @llvm.ppc.fcfud(double %a) +define dso_local double @test_fcfud(double %a) { +; CHECK-LABEL: test_fcfud: +; CHECK: # %bb.0: +; CHECK-NEXT: xscvuxddp 1, 1 +; CHECK-NEXT: blr + %1 = call double @llvm.ppc.fcfud(double %a) + ret double %1 +} + +declare double @llvm.ppc.fctid(double %a) +define dso_local double @test_fctid(double %a) { +; CHECK-LABEL: test_fctid: +; CHECK: # %bb.0: +; CHECK-NEXT: fctid 1, 1 +; CHECK-NEXT: blr + %1 = call double @llvm.ppc.fctid(double %a) + ret double %1 +} + +declare double @llvm.ppc.fctidz(double %a) +define dso_local double @test_fctidz(double %a) { +; CHECK-LABEL: test_fctidz: +; CHECK: # %bb.0: +; CHECK-NEXT: fctid 1, 1 +; CHECK-NEXT: blr + %1 = call double @llvm.ppc.fctid(double %a) + ret double %1 +} + +declare double @llvm.ppc.fctiw(double %a) +define dso_local double @test_fctiw(double %a) { +; CHECK-LABEL: test_fctiw: +; CHECK: # %bb.0: +; CHECK-NEXT: fctid 1, 1 +; CHECK-NEXT: blr + %1 = call double @llvm.ppc.fctid(double %a) + ret double %1 +} + +declare double @llvm.ppc.fctiwz(double %a) +define dso_local double @test_fctiwz(double %a) { +; CHECK-LABEL: test_fctiwz: +; CHECK: # %bb.0: +; CHECK-NEXT: fctid 1, 1 +; CHECK-NEXT: blr + %1 = call double @llvm.ppc.fctid(double %a) + ret double %1 +} + +declare double @llvm.ppc.fctudz(double %a) +define dso_local double @test_fctudz(double %a) { +; CHECK-LABEL: test_fctudz: +; CHECK: # %bb.0: +; CHECK-NEXT: fctid 1, 1 +; CHECK-NEXT: blr + %1 = call double @llvm.ppc.fctid(double %a) + ret double %1 +} + +declare double @llvm.ppc.fctuwz(double %a) +define dso_local double @test_fctuwz(double %a) { +; CHECK-LABEL: test_fctuwz: +; CHECK: # %bb.0: +; CHECK-NEXT: fctid 1, 1 +; CHECK-NEXT: blr + %1 = call double @llvm.ppc.fctid(double %a) + ret double %1 +} diff --git a/test/CodeGen/PowerPC/builtins-ppc-xlcompat-trap-64bit-only.ll b/test/CodeGen/PowerPC/builtins-ppc-xlcompat-trap-64bit-only.ll new file mode 100644 index 00000000000..3afdd6f262c --- /dev/null +++ b/test/CodeGen/PowerPC/builtins-ppc-xlcompat-trap-64bit-only.ll @@ -0,0 +1,136 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \ +; RUN: -mcpu=pwr8 < %s | FileCheck %s +; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu \ +; RUN: -mcpu=pwr7 < %s | FileCheck %s +; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-aix \ +; RUN: -mcpu=pwr8 < %s | FileCheck %s + +; tdw +declare void @llvm.ppc.tdw(i64 %a, i64 %b, i32 immarg) +define dso_local void @test__tdwlgt(i64 %a, i64 %b) { +; CHECK-LABEL: test__tdwlgt: +; CHECK: # %bb.0: +; CHECK-NEXT: tdlgt 3, 4 +; CHECK-NEXT: blr + call void @llvm.ppc.tdw(i64 %a, i64 %b, i32 1) + ret void +} + +define dso_local void @test__tdwllt(i64 %a, i64 %b) { +; CHECK-LABEL: test__tdwllt: +; CHECK: # %bb.0: +; CHECK-NEXT: tdllt 3, 4 +; CHECK-NEXT: blr + call void @llvm.ppc.tdw(i64 %a, i64 %b, i32 2) + ret void +} + +define dso_local void @test__tdw3(i64 %a, i64 %b) { +; CHECK-LABEL: test__tdw3: +; CHECK: # %bb.0: +; CHECK-NEXT: td 3, 3, 4 +; CHECK-NEXT: blr + call void @llvm.ppc.tdw(i64 %a, i64 %b, i32 3) + ret void +} +define dso_local void @test__tdweq(i64 %a, i64 %b) { +; CHECK-LABEL: test__tdweq: +; CHECK: # %bb.0: +; CHECK-NEXT: tdeq 3, 4 +; CHECK-NEXT: blr + call void @llvm.ppc.tdw(i64 %a, i64 %b, i32 4) + ret void +} + +define dso_local void @test__tdwlge(i64 %a, i64 %b) { +; CHECK-LABEL: test__tdwlge: +; CHECK: # %bb.0: +; CHECK-NEXT: td 5, 3, 4 +; CHECK-NEXT: blr + call void @llvm.ppc.tdw(i64 %a, i64 %b, i32 5) + ret void +} + +define dso_local void @test__tdwlle(i64 %a, i64 %b) { +; CHECK-LABEL: test__tdwlle: +; CHECK: # %bb.0: +; CHECK-NEXT: td 6, 3, 4 +; CHECK-NEXT: blr + call void @llvm.ppc.tdw(i64 %a, i64 %b, i32 6) + ret void +} + +define dso_local void @test__tdwgt(i64 %a, i64 %b) { +; CHECK-LABEL: test__tdwgt: +; CHECK: # %bb.0: +; CHECK-NEXT: tdgt 3, 4 +; CHECK-NEXT: blr + call void @llvm.ppc.tdw(i64 %a, i64 %b, i32 8) + ret void +} + +define dso_local void @test__tdwge(i64 %a, i64 %b) { +; CHECK-LABEL: test__tdwge: +; CHECK: # %bb.0: +; CHECK-NEXT: td 12, 3, 4 +; CHECK-NEXT: blr + call void @llvm.ppc.tdw(i64 %a, i64 %b, i32 12) + ret void +} + +define dso_local void @test__tdwlt(i64 %a, i64 %b) { +; CHECK-LABEL: test__tdwlt: +; CHECK: # %bb.0: +; CHECK-NEXT: tdlt 3, 4 +; CHECK-NEXT: blr + call void @llvm.ppc.tdw(i64 %a, i64 %b, i32 16) + ret void +} + +define dso_local void @test__tdwle(i64 %a, i64 %b) { +; CHECK-LABEL: test__tdwle: +; CHECK: # %bb.0: +; CHECK-NEXT: td 20, 3, 4 +; CHECK-NEXT: blr + call void @llvm.ppc.tdw(i64 %a, i64 %b, i32 20) + ret void +} + +define dso_local void @test__tdwne24(i64 %a, i64 %b) { +; CHECK-LABEL: test__tdwne24: +; CHECK: # %bb.0: +; CHECK-NEXT: tdne 3, 4 +; CHECK-NEXT: blr + call void @llvm.ppc.tdw(i64 %a, i64 %b, i32 24) + ret void +} + +define dso_local void @test__tdw31(i64 %a, i64 %b) { +; CHECK-LABEL: test__tdw31: +; CHECK: # %bb.0: +; CHECK-NEXT: tdu 3, 4 +; CHECK-NEXT: blr + call void @llvm.ppc.tdw(i64 %a, i64 %b, i32 31) + ret void +} + +define dso_local void @test__tdw_no_match(i64 %a, i64 %b) { +; CHECK-LABEL: test__tdw_no_match: +; CHECK: # %bb.0: +; CHECK-NEXT: td 13, 3, 4 +; CHECK-NEXT: blr + call void @llvm.ppc.tdw(i64 %a, i64 %b, i32 13) + ret void +} + +; trapd +declare void @llvm.ppc.trapd(i64 %a) +define dso_local void @test__trapd(i64 %a) { +; CHECK-LABEL: test__trapd: +; CHECK: # %bb.0: +; CHECK-NEXT: tdnei 3, 0 +; CHECK-NEXT: blr + call void @llvm.ppc.trapd(i64 %a) + ret void +} diff --git a/test/CodeGen/PowerPC/builtins-ppc-xlcompat-trap.ll b/test/CodeGen/PowerPC/builtins-ppc-xlcompat-trap.ll new file mode 100644 index 00000000000..406d98767f8 --- /dev/null +++ b/test/CodeGen/PowerPC/builtins-ppc-xlcompat-trap.ll @@ -0,0 +1,139 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \ +; RUN: -mcpu=pwr8 < %s | FileCheck %s +; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu \ +; RUN: -mcpu=pwr7 < %s | FileCheck %s +; RUN: llc -verify-machineinstrs -mtriple=powerpc-unknown-aix \ +; RUN: -mcpu=pwr8 < %s | FileCheck %s +; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-aix \ +; RUN: -mcpu=pwr8 < %s | FileCheck %s + +; tw +declare void @llvm.ppc.tw(i32 %a, i32 %b, i32 %c) +define dso_local void @test__twlgt(i32 %a, i32 %b) { +; CHECK-LABEL: test__twlgt: +; CHECK: # %bb.0: +; CHECK-NEXT: twlgt 3, 4 +; CHECK-NEXT: blr + call void @llvm.ppc.tw(i32 %a, i32 %b, i32 1) + ret void +} + +define dso_local void @test__twllt(i32 %a, i32 %b) { +; CHECK-LABEL: test__twllt: +; CHECK: # %bb.0: +; CHECK-NEXT: twllt 3, 4 +; CHECK-NEXT: blr + call void @llvm.ppc.tw(i32 %a, i32 %b, i32 2) + ret void +} + +define dso_local void @test__tw3(i32 %a, i32 %b) { +; CHECK-LABEL: test__tw3: +; CHECK: # %bb.0: +; CHECK-NEXT: tw 3, 3, 4 +; CHECK-NEXT: blr + call void @llvm.ppc.tw(i32 %a, i32 %b, i32 3) + ret void +} + +define dso_local void @test__tweq(i32 %a, i32 %b) { +; CHECK-LABEL: test__tweq: +; CHECK: # %bb.0: +; CHECK-NEXT: tweq 3, 4 +; CHECK-NEXT: blr + call void @llvm.ppc.tw(i32 %a, i32 %b, i32 4) + ret void +} + +define dso_local void @test__twlge(i32 %a, i32 %b) { +; CHECK-LABEL: test__twlge: +; CHECK: # %bb.0: +; CHECK-NEXT: tw 5, 3, 4 +; CHECK-NEXT: blr + call void @llvm.ppc.tw(i32 %a, i32 %b, i32 5) + ret void +} + +define dso_local void @test__twlle(i32 %a, i32 %b) { +; CHECK-LABEL: test__twlle: +; CHECK: # %bb.0: +; CHECK-NEXT: tw 6, 3, 4 +; CHECK-NEXT: blr + call void @llvm.ppc.tw(i32 %a, i32 %b, i32 6) + ret void +} + +define dso_local void @test__twgt(i32 %a, i32 %b) { +; CHECK-LABEL: test__twgt: +; CHECK: # %bb.0: +; CHECK-NEXT: twgt 3, 4 +; CHECK-NEXT: blr + call void @llvm.ppc.tw(i32 %a, i32 %b, i32 8) + ret void +} + +define dso_local void @test__twge(i32 %a, i32 %b) { +; CHECK-LABEL: test__twge: +; CHECK: # %bb.0: +; CHECK-NEXT: tw 12, 3, 4 +; CHECK-NEXT: blr + call void @llvm.ppc.tw(i32 %a, i32 %b, i32 12) + ret void +} + +define dso_local void @test__twlt(i32 %a, i32 %b) { +; CHECK-LABEL: test__twlt: +; CHECK: # %bb.0: +; CHECK-NEXT: twlt 3, 4 +; CHECK-NEXT: blr + call void @llvm.ppc.tw(i32 %a, i32 %b, i32 16) + ret void +} + +define dso_local void @test__twle(i32 %a, i32 %b) { +; CHECK-LABEL: test__twle: +; CHECK: # %bb.0: +; CHECK-NEXT: tw 20, 3, 4 +; CHECK-NEXT: blr + call void @llvm.ppc.tw(i32 %a, i32 %b, i32 20) + ret void +} + +define dso_local void @test__twne24(i32 %a, i32 %b) { +; CHECK-LABEL: test__twne24: +; CHECK: # %bb.0: +; CHECK-NEXT: twne 3, 4 +; CHECK-NEXT: blr + call void @llvm.ppc.tw(i32 %a, i32 %b, i32 24) + ret void +} + +define dso_local void @test__twu(i32 %a, i32 %b) { +; CHECK-LABEL: test__twu: +; CHECK: # %bb.0: +; CHECK-NEXT: twu 3, 4 +; CHECK-NEXT: blr + call void @llvm.ppc.tw(i32 %a, i32 %b, i32 31) + ret void +} + +define dso_local void @test__tw_no_match(i32 %a, i32 %b) { +; CHECK-LABEL: test__tw_no_match: +; CHECK: # %bb.0: +; CHECK-NEXT: tw 13, 3, 4 +; CHECK-NEXT: blr + call void @llvm.ppc.tw(i32 %a, i32 %b, i32 13) + ret void +} + +; trap +declare void @llvm.ppc.trap(i32 %a) +define dso_local void @test__trap(i32 %a) { +; CHECK-LABEL: test__trap: +; CHECK: # %bb.0: +; CHECK-NEXT: twnei 3, 0 +; CHECK-NEXT: blr + call void @llvm.ppc.trap(i32 %a) + ret void +}