From ccdfd7f7e6225a3e455ae3633cf8c5915a0b3529 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Mon, 24 Jul 2017 21:28:32 +0000 Subject: [PATCH 1/8] Add mradds to the powerpc intrinsics --- src/etc/platform-intrinsics/powerpc.json | 7 +++++++ src/librustc_platform_intrinsics/powerpc.rs | 5 +++++ 2 files changed, 12 insertions(+) diff --git a/src/etc/platform-intrinsics/powerpc.json b/src/etc/platform-intrinsics/powerpc.json index 5a7e986b532c4..34a4dea7744bb 100644 --- a/src/etc/platform-intrinsics/powerpc.json +++ b/src/etc/platform-intrinsics/powerpc.json @@ -16,6 +16,13 @@ "llvm": "vperm", "ret": "s32", "args": ["0", "0", "s8"] + }, + { + "intrinsic": "mradds", + "width": [128], + "llvm": "vmhraddshs", + "ret": "s16", + "args": ["0", "0", "0"] } ] } diff --git a/src/librustc_platform_intrinsics/powerpc.rs b/src/librustc_platform_intrinsics/powerpc.rs index 31b642b4055b9..90e95ec6ae153 100644 --- a/src/librustc_platform_intrinsics/powerpc.rs +++ b/src/librustc_platform_intrinsics/powerpc.rs @@ -27,6 +27,11 @@ pub fn find(name: &str) -> Option { output: &::I32x4, definition: Named("llvm.ppc.altivec.vperm") }, + "_vec_mradds" => Intrinsic { + inputs: { static INPUTS: [&'static Type; 3] = [&::I16x8, &::I16x8, &::I16x8]; &INPUTS }, + output: &::I16x8, + definition: Named("llvm.ppc.altivec.vmhraddshs") + }, _ => return None, }) } From 4f6c03e24394131f2cd50eab8002cf40274cbf0d Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Wed, 26 Jul 2017 09:58:17 +0000 Subject: [PATCH 2/8] Add Vector Compare Bounds Floating-Point --- src/etc/platform-intrinsics/powerpc.json | 10 +++++++++- src/librustc_platform_intrinsics/powerpc.rs | 5 +++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/etc/platform-intrinsics/powerpc.json b/src/etc/platform-intrinsics/powerpc.json index 34a4dea7744bb..32648c96e4c90 100644 --- a/src/etc/platform-intrinsics/powerpc.json +++ b/src/etc/platform-intrinsics/powerpc.json @@ -4,7 +4,8 @@ "llvm_prefix": "llvm.ppc.altivec.", "number_info": { "unsigned": {}, - "signed": {} + "signed": {}, + "float": {} }, "width_info": { "128": { "width": "" } @@ -23,6 +24,13 @@ "llvm": "vmhraddshs", "ret": "s16", "args": ["0", "0", "0"] + }, + { + "intrinsic": "cmpb", + "width": [128], + "llvm": "vcmpbfp", + "ret": "s32", + "args": ["f32", "f32"] } ] } diff --git a/src/librustc_platform_intrinsics/powerpc.rs b/src/librustc_platform_intrinsics/powerpc.rs index 90e95ec6ae153..e2c5a20349588 100644 --- a/src/librustc_platform_intrinsics/powerpc.rs +++ b/src/librustc_platform_intrinsics/powerpc.rs @@ -32,6 +32,11 @@ pub fn find(name: &str) -> Option { output: &::I16x8, definition: Named("llvm.ppc.altivec.vmhraddshs") }, + "_vec_cmpb" => Intrinsic { + inputs: { static INPUTS: [&'static Type; 2] = [&::F32x4, &::F32x4]; &INPUTS }, + output: &::I32x4, + definition: Named("llvm.ppc.altivec.vcmpbfp") + }, _ => return None, }) } From e2b5a6b3bc4fcebbd1909186ae0398e8d2c29521 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Wed, 26 Jul 2017 09:58:17 +0000 Subject: [PATCH 3/8] Add Vector Compare Equal --- src/etc/platform-intrinsics/powerpc.json | 15 +++++++++++++-- src/librustc_platform_intrinsics/powerpc.rs | 15 +++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/etc/platform-intrinsics/powerpc.json b/src/etc/platform-intrinsics/powerpc.json index 32648c96e4c90..80ec7e956f85c 100644 --- a/src/etc/platform-intrinsics/powerpc.json +++ b/src/etc/platform-intrinsics/powerpc.json @@ -3,8 +3,12 @@ "intrinsic_prefix": "_vec_", "llvm_prefix": "llvm.ppc.altivec.", "number_info": { - "unsigned": {}, - "signed": {}, + "unsigned": { + "data_type_short": { "8": "b", "16": "h", "32": "w", "64": "d" } + }, + "signed": { + "data_type_short": { "8": "b", "16": "h", "32": "w", "64": "d" } + }, "float": {} }, "width_info": { @@ -31,6 +35,13 @@ "llvm": "vcmpbfp", "ret": "s32", "args": ["f32", "f32"] + }, + { + "intrinsic": "cmpeq{0.data_type_short}", + "width": [128], + "llvm": "vcmpequ{0.data_type_short}", + "ret": "s(8-32)", + "args": ["0", "0"] } ] } diff --git a/src/librustc_platform_intrinsics/powerpc.rs b/src/librustc_platform_intrinsics/powerpc.rs index e2c5a20349588..3fa248d75d903 100644 --- a/src/librustc_platform_intrinsics/powerpc.rs +++ b/src/librustc_platform_intrinsics/powerpc.rs @@ -37,6 +37,21 @@ pub fn find(name: &str) -> Option { output: &::I32x4, definition: Named("llvm.ppc.altivec.vcmpbfp") }, + "_vec_cmpeqb" => Intrinsic { + inputs: { static INPUTS: [&'static Type; 2] = [&::I8x16, &::I8x16]; &INPUTS }, + output: &::I8x16, + definition: Named("llvm.ppc.altivec.vcmpequb") + }, + "_vec_cmpeqh" => Intrinsic { + inputs: { static INPUTS: [&'static Type; 2] = [&::I16x8, &::I16x8]; &INPUTS }, + output: &::I16x8, + definition: Named("llvm.ppc.altivec.vcmpequh") + }, + "_vec_cmpeqw" => Intrinsic { + inputs: { static INPUTS: [&'static Type; 2] = [&::I32x4, &::I32x4]; &INPUTS }, + output: &::I32x4, + definition: Named("llvm.ppc.altivec.vcmpequw") + }, _ => return None, }) } From a1995d3973e6ac28c9356d3beb53fba410aebf83 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Wed, 26 Jul 2017 09:58:17 +0000 Subject: [PATCH 4/8] Add Vector Compare Greater-Than --- src/etc/platform-intrinsics/powerpc.json | 16 +++++++++++ src/librustc_platform_intrinsics/powerpc.rs | 30 +++++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/src/etc/platform-intrinsics/powerpc.json b/src/etc/platform-intrinsics/powerpc.json index 80ec7e956f85c..55a199945f16b 100644 --- a/src/etc/platform-intrinsics/powerpc.json +++ b/src/etc/platform-intrinsics/powerpc.json @@ -4,9 +4,11 @@ "llvm_prefix": "llvm.ppc.altivec.", "number_info": { "unsigned": { + "kind" : "u", "data_type_short": { "8": "b", "16": "h", "32": "w", "64": "d" } }, "signed": { + "kind" : "s", "data_type_short": { "8": "b", "16": "h", "32": "w", "64": "d" } }, "float": {} @@ -42,6 +44,20 @@ "llvm": "vcmpequ{0.data_type_short}", "ret": "s(8-32)", "args": ["0", "0"] + }, + { + "intrinsic": "cmpgt{1.kind}{1.data_type_short}", + "width": [128], + "llvm": "vcmpgt{1.kind}{1.data_type_short}", + "ret": "s(8-32)", + "args": ["0u", "1"] + }, + { + "intrinsic": "cmpgt{1.kind}{1.data_type_short}", + "width": [128], + "llvm": "vcmpgt{1.kind}{1.data_type_short}", + "ret": "s(8-32)", + "args": ["0", "1"] } ] } diff --git a/src/librustc_platform_intrinsics/powerpc.rs b/src/librustc_platform_intrinsics/powerpc.rs index 3fa248d75d903..4be738eed81fc 100644 --- a/src/librustc_platform_intrinsics/powerpc.rs +++ b/src/librustc_platform_intrinsics/powerpc.rs @@ -52,6 +52,36 @@ pub fn find(name: &str) -> Option { output: &::I32x4, definition: Named("llvm.ppc.altivec.vcmpequw") }, + "_vec_cmpgtub" => Intrinsic { + inputs: { static INPUTS: [&'static Type; 2] = [&::U8x16, &::U8x16]; &INPUTS }, + output: &::I8x16, + definition: Named("llvm.ppc.altivec.vcmpgtub") + }, + "_vec_cmpgtuh" => Intrinsic { + inputs: { static INPUTS: [&'static Type; 2] = [&::U16x8, &::U16x8]; &INPUTS }, + output: &::I16x8, + definition: Named("llvm.ppc.altivec.vcmpgtuh") + }, + "_vec_cmpgtuw" => Intrinsic { + inputs: { static INPUTS: [&'static Type; 2] = [&::U32x4, &::U32x4]; &INPUTS }, + output: &::I32x4, + definition: Named("llvm.ppc.altivec.vcmpgtuw") + }, + "_vec_cmpgtsb" => Intrinsic { + inputs: { static INPUTS: [&'static Type; 2] = [&::I8x16, &::I8x16]; &INPUTS }, + output: &::I8x16, + definition: Named("llvm.ppc.altivec.vcmpgtsb") + }, + "_vec_cmpgtsh" => Intrinsic { + inputs: { static INPUTS: [&'static Type; 2] = [&::I16x8, &::I16x8]; &INPUTS }, + output: &::I16x8, + definition: Named("llvm.ppc.altivec.vcmpgtsh") + }, + "_vec_cmpgtsw" => Intrinsic { + inputs: { static INPUTS: [&'static Type; 2] = [&::I32x4, &::I32x4]; &INPUTS }, + output: &::I32x4, + definition: Named("llvm.ppc.altivec.vcmpgtsw") + }, _ => return None, }) } From ade5ead38e3ce4565e9b3a1fc06733c336114044 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Thu, 27 Jul 2017 13:30:51 +0000 Subject: [PATCH 5/8] Add support for the Power8 and Power9 features on PowerPC --- src/librustc_trans/llvm_util.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/librustc_trans/llvm_util.rs b/src/librustc_trans/llvm_util.rs index 99ab1c47bed31..448feb5259ddd 100644 --- a/src/librustc_trans/llvm_util.rs +++ b/src/librustc_trans/llvm_util.rs @@ -80,7 +80,10 @@ const X86_WHITELIST: &'static [&'static str] = &["avx\0", "avx2\0", "bmi\0", "bm const HEXAGON_WHITELIST: &'static [&'static str] = &["hvx\0", "hvx-double\0"]; -const POWERPC_WHITELIST: &'static [&'static str] = &["altivec\0", "vsx\0"]; +const POWERPC_WHITELIST: &'static [&'static str] = &["altivec\0", + "power8-altivec\0", "power9-altivec\0", + "power8-vector\0", "power9-vector\0", + "vsx\0"]; pub fn target_features(sess: &Session) -> Vec { let target_machine = create_target_machine(sess); From a718c813ed8546b0959de78aae22846c1ea9a783 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Thu, 27 Jul 2017 13:30:51 +0000 Subject: [PATCH 6/8] Add support for Vector Maximum on PowerPC --- src/etc/platform-intrinsics/powerpc.json | 7 +++++ src/librustc_platform_intrinsics/powerpc.rs | 30 +++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/src/etc/platform-intrinsics/powerpc.json b/src/etc/platform-intrinsics/powerpc.json index 55a199945f16b..aaab224297ee9 100644 --- a/src/etc/platform-intrinsics/powerpc.json +++ b/src/etc/platform-intrinsics/powerpc.json @@ -58,6 +58,13 @@ "llvm": "vcmpgt{1.kind}{1.data_type_short}", "ret": "s(8-32)", "args": ["0", "1"] + }, + { + "intrinsic": "max{0.kind}{0.data_type_short}", + "width": [128], + "llvm": "vmax{0.kind}{0.data_type_short}", + "ret": "i(8-32)", + "args": ["0", "0"] } ] } diff --git a/src/librustc_platform_intrinsics/powerpc.rs b/src/librustc_platform_intrinsics/powerpc.rs index 4be738eed81fc..327299a0d0596 100644 --- a/src/librustc_platform_intrinsics/powerpc.rs +++ b/src/librustc_platform_intrinsics/powerpc.rs @@ -82,6 +82,36 @@ pub fn find(name: &str) -> Option { output: &::I32x4, definition: Named("llvm.ppc.altivec.vcmpgtsw") }, + "_vec_maxsb" => Intrinsic { + inputs: { static INPUTS: [&'static Type; 2] = [&::I8x16, &::I8x16]; &INPUTS }, + output: &::I8x16, + definition: Named("llvm.ppc.altivec.vmaxsb") + }, + "_vec_maxub" => Intrinsic { + inputs: { static INPUTS: [&'static Type; 2] = [&::U8x16, &::U8x16]; &INPUTS }, + output: &::U8x16, + definition: Named("llvm.ppc.altivec.vmaxub") + }, + "_vec_maxsh" => Intrinsic { + inputs: { static INPUTS: [&'static Type; 2] = [&::I16x8, &::I16x8]; &INPUTS }, + output: &::I16x8, + definition: Named("llvm.ppc.altivec.vmaxsh") + }, + "_vec_maxuh" => Intrinsic { + inputs: { static INPUTS: [&'static Type; 2] = [&::U16x8, &::U16x8]; &INPUTS }, + output: &::U16x8, + definition: Named("llvm.ppc.altivec.vmaxuh") + }, + "_vec_maxsw" => Intrinsic { + inputs: { static INPUTS: [&'static Type; 2] = [&::I32x4, &::I32x4]; &INPUTS }, + output: &::I32x4, + definition: Named("llvm.ppc.altivec.vmaxsw") + }, + "_vec_maxuw" => Intrinsic { + inputs: { static INPUTS: [&'static Type; 2] = [&::U32x4, &::U32x4]; &INPUTS }, + output: &::U32x4, + definition: Named("llvm.ppc.altivec.vmaxuw") + }, _ => return None, }) } From cbce0aa341c8be3f4b9253c93ed641ed454fc0a0 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Thu, 27 Jul 2017 13:30:51 +0000 Subject: [PATCH 7/8] Add support for Vector Minimum on PowerPC --- src/etc/platform-intrinsics/powerpc.json | 7 +++++ src/librustc_platform_intrinsics/powerpc.rs | 30 +++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/src/etc/platform-intrinsics/powerpc.json b/src/etc/platform-intrinsics/powerpc.json index aaab224297ee9..7f01aaa3ac113 100644 --- a/src/etc/platform-intrinsics/powerpc.json +++ b/src/etc/platform-intrinsics/powerpc.json @@ -65,6 +65,13 @@ "llvm": "vmax{0.kind}{0.data_type_short}", "ret": "i(8-32)", "args": ["0", "0"] + }, + { + "intrinsic": "min{0.kind}{0.data_type_short}", + "width": [128], + "llvm": "vmin{0.kind}{0.data_type_short}", + "ret": "i(8-32)", + "args": ["0", "0"] } ] } diff --git a/src/librustc_platform_intrinsics/powerpc.rs b/src/librustc_platform_intrinsics/powerpc.rs index 327299a0d0596..60074cce2b9a3 100644 --- a/src/librustc_platform_intrinsics/powerpc.rs +++ b/src/librustc_platform_intrinsics/powerpc.rs @@ -112,6 +112,36 @@ pub fn find(name: &str) -> Option { output: &::U32x4, definition: Named("llvm.ppc.altivec.vmaxuw") }, + "_vec_minsb" => Intrinsic { + inputs: { static INPUTS: [&'static Type; 2] = [&::I8x16, &::I8x16]; &INPUTS }, + output: &::I8x16, + definition: Named("llvm.ppc.altivec.vminsb") + }, + "_vec_minub" => Intrinsic { + inputs: { static INPUTS: [&'static Type; 2] = [&::U8x16, &::U8x16]; &INPUTS }, + output: &::U8x16, + definition: Named("llvm.ppc.altivec.vminub") + }, + "_vec_minsh" => Intrinsic { + inputs: { static INPUTS: [&'static Type; 2] = [&::I16x8, &::I16x8]; &INPUTS }, + output: &::I16x8, + definition: Named("llvm.ppc.altivec.vminsh") + }, + "_vec_minuh" => Intrinsic { + inputs: { static INPUTS: [&'static Type; 2] = [&::U16x8, &::U16x8]; &INPUTS }, + output: &::U16x8, + definition: Named("llvm.ppc.altivec.vminuh") + }, + "_vec_minsw" => Intrinsic { + inputs: { static INPUTS: [&'static Type; 2] = [&::I32x4, &::I32x4]; &INPUTS }, + output: &::I32x4, + definition: Named("llvm.ppc.altivec.vminsw") + }, + "_vec_minuw" => Intrinsic { + inputs: { static INPUTS: [&'static Type; 2] = [&::U32x4, &::U32x4]; &INPUTS }, + output: &::U32x4, + definition: Named("llvm.ppc.altivec.vminuw") + }, _ => return None, }) } From c4710203c098b68b5f80b1507e889ad894855729 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Fri, 28 Jul 2017 02:03:23 +0000 Subject: [PATCH 8/8] Make LLVMRustHasFeature more robust The function should accept feature strings that old LLVM might not support. Simplify the code using the same approach used by LLVMRustPrintTargetFeatures. Dummify the function for non 4.0 LLVM and update the tests accordingly. --- src/rustllvm/PassWrapper.cpp | 20 +++++++------------- src/test/run-make/print-cfg/Makefile | 2 +- src/test/run-pass/sse2.rs | 1 + 3 files changed, 9 insertions(+), 14 deletions(-) diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index 7fb1eafb30da7..57e90be27748f 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -181,20 +181,14 @@ extern "C" bool LLVMRustHasFeature(LLVMTargetMachineRef TM, TargetMachine *Target = unwrap(TM); const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo(); const FeatureBitset &Bits = MCInfo->getFeatureBits(); - const llvm::SubtargetFeatureKV *FeatureEntry; - -#define SUBTARGET(x) \ - if (MCInfo->isCPUStringValid(x##SubTypeKV[0].Key)) { \ - FeatureEntry = x##FeatureKV; \ - } else - - GEN_SUBTARGETS { return false; } -#undef SUBTARGET - - while (strcmp(Feature, FeatureEntry->Key) != 0) - FeatureEntry++; +#if LLVM_VERSION_GE(4, 0) + const ArrayRef FeatTable = MCInfo->getFeatureTable(); - return (Bits & FeatureEntry->Value) == FeatureEntry->Value; + for (auto &FeatureEntry : FeatTable) + if (!strcmp(FeatureEntry.Key, Feature)) + return (Bits & FeatureEntry.Value) == FeatureEntry.Value; +#endif + return false; } enum class LLVMRustCodeModel { diff --git a/src/test/run-make/print-cfg/Makefile b/src/test/run-make/print-cfg/Makefile index a820a463f4a02..82fa3f6a3c5e0 100644 --- a/src/test/run-make/print-cfg/Makefile +++ b/src/test/run-make/print-cfg/Makefile @@ -5,7 +5,7 @@ all: default $(RUSTC) --target x86_64-pc-windows-gnu --print cfg | grep x86_64 $(RUSTC) --target i686-pc-windows-msvc --print cfg | grep msvc $(RUSTC) --target i686-apple-darwin --print cfg | grep macos - $(RUSTC) --target i686-unknown-linux-gnu --print cfg | grep sse2 + $(RUSTC) --target i686-unknown-linux-gnu --print cfg | grep gnu ifdef IS_WINDOWS default: diff --git a/src/test/run-pass/sse2.rs b/src/test/run-pass/sse2.rs index 8d88c17af79b3..c27f83011cb1b 100644 --- a/src/test/run-pass/sse2.rs +++ b/src/test/run-pass/sse2.rs @@ -7,6 +7,7 @@ // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. +// min-llvm-version 4.0 #![feature(cfg_target_feature)]