Index: include/llvm/IR/IntrinsicsPowerPC.td =================================================================== --- include/llvm/IR/IntrinsicsPowerPC.td +++ include/llvm/IR/IntrinsicsPowerPC.td @@ -687,6 +687,32 @@ // Vector divide. def int_ppc_vsx_xvdivdp : PowerPC_VSX_Vec_DDD_Intrinsic<"xvdivdp">; def int_ppc_vsx_xvdivsp : PowerPC_VSX_Vec_FFF_Intrinsic<"xvdivsp">; + +// Vector round-to-infinity (ceil) +def int_ppc_vsx_xvrspip : + Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty], [IntrNoMem]>; +def int_ppc_vsx_xvrdpip : + Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty], [IntrNoMem]>; + +// Vector compare +def int_ppc_vsx_xvcmpeqdp : + PowerPC_VSX_Intrinsic<"xvcmpeqdp", [llvm_v2i64_ty], + [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>; +def int_ppc_vsx_xvcmpeqsp : + PowerPC_VSX_Intrinsic<"xvcmpeqsp", [llvm_v4i32_ty], + [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>; +def int_ppc_vsx_xvcmpgedp : + PowerPC_VSX_Intrinsic<"xvcmpgedp", [llvm_v2i64_ty], + [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>; +def int_ppc_vsx_xvcmpgesp : + PowerPC_VSX_Intrinsic<"xvcmpgesp", [llvm_v4i32_ty], + [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>; +def int_ppc_vsx_xvcmpgtdp : + PowerPC_VSX_Intrinsic<"xvcmpgtdp", [llvm_v2i64_ty], + [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>; +def int_ppc_vsx_xvcmpgtsp : + PowerPC_VSX_Intrinsic<"xvcmpgtsp", [llvm_v4i32_ty], + [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>; } //===----------------------------------------------------------------------===// Index: lib/Target/PowerPC/PPCInstrVSX.td =================================================================== --- lib/Target/PowerPC/PPCInstrVSX.td +++ lib/Target/PowerPC/PPCInstrVSX.td @@ -457,22 +457,34 @@ defm XVCMPEQDP : XX3Form_Rcr<60, 99, (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), - "xvcmpeqdp", "$XT, $XA, $XB", IIC_VecFPCompare, []>; + "xvcmpeqdp", "$XT, $XA, $XB", IIC_VecFPCompare, + [(set v2i64:$XT, + (int_ppc_vsx_xvcmpeqdp v2f64:$XA, v2f64:$XB))]>; defm XVCMPEQSP : XX3Form_Rcr<60, 67, (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), - "xvcmpeqsp", "$XT, $XA, $XB", IIC_VecFPCompare, []>; + "xvcmpeqsp", "$XT, $XA, $XB", IIC_VecFPCompare, + [(set v4i32:$XT, + (int_ppc_vsx_xvcmpeqsp v4f32:$XA, v4f32:$XB))]>; defm XVCMPGEDP : XX3Form_Rcr<60, 115, (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), - "xvcmpgedp", "$XT, $XA, $XB", IIC_VecFPCompare, []>; + "xvcmpgedp", "$XT, $XA, $XB", IIC_VecFPCompare, + [(set v2i64:$XT, + (int_ppc_vsx_xvcmpgedp v2f64:$XA, v2f64:$XB))]>; defm XVCMPGESP : XX3Form_Rcr<60, 83, (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), - "xvcmpgesp", "$XT, $XA, $XB", IIC_VecFPCompare, []>; + "xvcmpgesp", "$XT, $XA, $XB", IIC_VecFPCompare, + [(set v4i32:$XT, + (int_ppc_vsx_xvcmpgesp v4f32:$XA, v4f32:$XB))]>; defm XVCMPGTDP : XX3Form_Rcr<60, 107, (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), - "xvcmpgtdp", "$XT, $XA, $XB", IIC_VecFPCompare, []>; + "xvcmpgtdp", "$XT, $XA, $XB", IIC_VecFPCompare, + [(set v2i64:$XT, + (int_ppc_vsx_xvcmpgtdp v2f64:$XA, v2f64:$XB))]>; defm XVCMPGTSP : XX3Form_Rcr<60, 75, (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), - "xvcmpgtsp", "$XT, $XA, $XB", IIC_VecFPCompare, []>; + "xvcmpgtsp", "$XT, $XA, $XB", IIC_VecFPCompare, + [(set v4i32:$XT, + (int_ppc_vsx_xvcmpgtsp v4f32:$XA, v4f32:$XB))]>; // Move Instructions def XSABSDP : XX2Form<60, 345, Index: test/CodeGen/PowerPC/builtins-ppc-elf2-abi.ll =================================================================== --- test/CodeGen/PowerPC/builtins-ppc-elf2-abi.ll +++ test/CodeGen/PowerPC/builtins-ppc-elf2-abi.ll @@ -0,0 +1,165 @@ +; RUN: llc -mtriple=powerpc64le-unknown-linux-gnu -mcpu=pwr8 < %s | FileCheck %s +; RUN: llc -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr8 < %s | FileCheck %s + +@vda = common global <2 x double> zeroinitializer, align 16 +@vdb = common global <2 x double> zeroinitializer, align 16 +@vdr = common global <2 x double> zeroinitializer, align 16 +@vfa = common global <4 x float> zeroinitializer, align 16 +@vfb = common global <4 x float> zeroinitializer, align 16 +@vfr = common global <4 x float> zeroinitializer, align 16 +@vbllr = common global <2 x i64> zeroinitializer, align 16 +@vbir = common global <4 x i32> zeroinitializer, align 16 +@vblla = common global <2 x i64> zeroinitializer, align 16 +@vbllb = common global <2 x i64> zeroinitializer, align 16 +@vbia = common global <4 x i32> zeroinitializer, align 16 +@vbib = common global <4 x i32> zeroinitializer, align 16 + +; Function Attrs: nounwind +define void @test1() { +entry: + %0 = load <2 x double>, <2 x double>* @vda, align 16 + %1 = load <2 x double>, <2 x double>* @vdb, align 16 + %2 = call <2 x double> @llvm.ppc.vsx.xvdivdp(<2 x double> %0, <2 x double> %1) + store <2 x double> %2, <2 x double>* @vdr, align 16 + ret void +; CHECK-LABEL: @test1 +; CHECK: xvdivdp {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +} + +; Function Attrs: nounwind +define void @test2() { +entry: + %0 = load <4 x float>, <4 x float>* @vfa, align 16 + %1 = load <4 x float>, <4 x float>* @vfb, align 16 + %2 = call <4 x float> @llvm.ppc.vsx.xvdivsp(<4 x float> %0, <4 x float> %1) + store <4 x float> %2, <4 x float>* @vfr, align 16 + ret void +; CHECK-LABEL: @test2 +; CHECK: xvdivsp {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +} + +; Function Attrs: nounwind +define void @test3() { +entry: + %0 = load <2 x double>, <2 x double>* @vda, align 16 + %1 = load <2 x double>, <2 x double>* @vda, align 16 + %2 = call <2 x double> @llvm.ceil.v2f64(<2 x double> %1) + store <2 x double> %2, <2 x double>* @vdr, align 16 + ret void +; CHECK-LABEL: @test3 +; CHECK: xvrdpip {{[0-9]+}}, {{[0-9]+}} +} + +; Function Attrs: nounwind +define void @test4() { +entry: + %0 = load <4 x float>, <4 x float>* @vfa, align 16 + %1 = load <4 x float>, <4 x float>* @vfa, align 16 + %2 = call <4 x float> @llvm.ceil.v4f32(<4 x float> %1) + store <4 x float> %2, <4 x float>* @vfr, align 16 + ret void +; CHECK-LABEL: @test4 +; CHECK: xvrspip {{[0-9]+}}, {{[0-9]+}} +} + +; Function Attrs: nounwind +define void @test5() { +entry: + %0 = load <2 x double>, <2 x double>* @vda, align 16 + %1 = load <2 x double>, <2 x double>* @vdb, align 16 + %2 = call <2 x i64> @llvm.ppc.vsx.xvcmpeqdp(<2 x double> %0, <2 x double> %1) + store <2 x i64> %2, <2 x i64>* @vbllr, align 16 + ret void +; CHECK-LABEL: @test5 +; CHECK: xvcmpeqdp {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +} + +; Function Attrs: nounwind +define void @test6() { +entry: + %0 = load <4 x float>, <4 x float>* @vfa, align 16 + %1 = load <4 x float>, <4 x float>* @vfb, align 16 + %2 = call <4 x i32> @llvm.ppc.vsx.xvcmpeqsp(<4 x float> %0, <4 x float> %1) + store <4 x i32> %2, <4 x i32>* @vbir, align 16 + ret void +; CHECK-LABEL: @test6 +; CHECK: xvcmpeqsp {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +} + +; Function Attrs: nounwind +define void @test7() { +entry: + %0 = load <2 x double>, <2 x double>* @vda, align 16 + %1 = load <2 x double>, <2 x double>* @vdb, align 16 + %2 = call <2 x i64> @llvm.ppc.vsx.xvcmpgedp(<2 x double> %0, <2 x double> %1) + store <2 x i64> %2, <2 x i64>* @vbllr, align 16 + ret void +; CHECK-LABEL: @test7 +; CHECK: xvcmpgedp {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +} + +; Function Attrs: nounwind +define void @test8() { +entry: + %0 = load <4 x float>, <4 x float>* @vfa, align 16 + %1 = load <4 x float>, <4 x float>* @vfb, align 16 + %2 = call <4 x i32> @llvm.ppc.vsx.xvcmpgesp(<4 x float> %0, <4 x float> %1) + store <4 x i32> %2, <4 x i32>* @vbir, align 16 + ret void +; CHECK-LABEL: @test8 +; CHECK: xvcmpgesp {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +} + +; Function Attrs: nounwind +define void @test9() { +entry: + %0 = load <2 x double>, <2 x double>* @vda, align 16 + %1 = load <2 x double>, <2 x double>* @vdb, align 16 + %2 = call <2 x i64> @llvm.ppc.vsx.xvcmpgtdp(<2 x double> %0, <2 x double> %1) + store <2 x i64> %2, <2 x i64>* @vbllr, align 16 + ret void +; CHECK-LABEL: @test9 +; CHECK: xvcmpgtdp {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +} + +; Function Attrs: nounwind +define void @test10() { +entry: + %0 = load <4 x float>, <4 x float>* @vfa, align 16 + %1 = load <4 x float>, <4 x float>* @vfb, align 16 + %2 = call <4 x i32> @llvm.ppc.vsx.xvcmpgtsp(<4 x float> %0, <4 x float> %1) + store <4 x i32> %2, <4 x i32>* @vbir, align 16 + ret void +; CHECK-LABEL: @test10 +; CHECK: xvcmpgtsp {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +} + +; Function Attrs: nounwind readnone +declare <2 x double> @llvm.ceil.v2f64(<2 x double>) + +; Function Attrs: nounwind readnone +declare <4 x float> @llvm.ceil.v4f32(<4 x float>) + +; Function Attrs: nounwind readnone +declare <2 x double> @llvm.ppc.vsx.xvdivdp(<2 x double>, <2 x double>) + +; Function Attrs: nounwind readnone +declare <4 x float> @llvm.ppc.vsx.xvdivsp(<4 x float>, <4 x float>) + +; Function Attrs: nounwind readnone +declare <2 x i64> @llvm.ppc.vsx.xvcmpeqdp(<2 x double>, <2 x double>) + +; Function Attrs: nounwind readnone +declare <4 x i32> @llvm.ppc.vsx.xvcmpeqsp(<4 x float>, <4 x float>) + +; Function Attrs: nounwind readnone +declare <2 x i64> @llvm.ppc.vsx.xvcmpgedp(<2 x double>, <2 x double>) + +; Function Attrs: nounwind readnone +declare <4 x i32> @llvm.ppc.vsx.xvcmpgesp(<4 x float>, <4 x float>) + +; Function Attrs: nounwind readnone +declare <2 x i64> @llvm.ppc.vsx.xvcmpgtdp(<2 x double>, <2 x double>) + +; Function Attrs: nounwind readnone +declare <4 x i32> @llvm.ppc.vsx.xvcmpgtsp(<4 x float>, <4 x float>)