[PATCH] D46881: [X86][CET] Changing -fcf-protection behavior to comply with gcc (clang part)
This revision was automatically updated to reflect the committed changes. Closed by commit rC332704: This patch aims to match the changes introduced (authored by aivchenk, committed by ). Changed prior to commit: https://reviews.llvm.org/D46881?vs=147292&id=147476#toc Repository: rC Clang https://reviews.llvm.org/D46881 Files: docs/ClangCommandLineReference.rst include/clang/Basic/DiagnosticCommonKinds.td include/clang/Basic/TargetInfo.h include/clang/Driver/Options.td lib/Basic/TargetInfo.cpp lib/Basic/Targets/X86.cpp lib/Basic/Targets/X86.h lib/Frontend/CompilerInvocation.cpp test/CodeGen/attributes.c test/CodeGen/builtins-x86.c test/CodeGen/x86-cf-protection.c test/Driver/x86-target-features.c test/Preprocessor/x86_target_features.c test/Sema/attr-nocf_check.c test/Sema/attr-nocf_check.cpp Index: lib/Basic/TargetInfo.cpp === --- lib/Basic/TargetInfo.cpp +++ lib/Basic/TargetInfo.cpp @@ -14,6 +14,7 @@ #include "clang/Basic/TargetInfo.h" #include "clang/Basic/AddressSpaces.h" #include "clang/Basic/CharInfo.h" +#include "clang/Basic/Diagnostic.h" #include "clang/Basic/LangOptions.h" #include "llvm/ADT/APFloat.h" #include "llvm/ADT/STLExtras.h" @@ -115,6 +116,18 @@ // Out of line virtual dtor for TargetInfo. TargetInfo::~TargetInfo() {} +bool +TargetInfo::checkCFProtectionBranchSupported(DiagnosticsEngine &Diags) const { + Diags.Report(diag::err_opt_not_valid_on_target) << "cf-protection=branch"; + return false; +} + +bool +TargetInfo::checkCFProtectionReturnSupported(DiagnosticsEngine &Diags) const { + Diags.Report(diag::err_opt_not_valid_on_target) << "cf-protection=return"; + return false; +} + /// getTypeName - Return the user string for the specified integer type enum. /// For example, SignedShort -> "short". const char *TargetInfo::getTypeName(IntType T) { Index: lib/Basic/Targets/X86.h === --- lib/Basic/Targets/X86.h +++ lib/Basic/Targets/X86.h @@ -81,7 +81,6 @@ bool HasSHA = false; bool HasMPX = false; bool HasSHSTK = false; - bool HasIBT = false; bool HasSGX = false; bool HasCX16 = false; bool HasFXSR = false; @@ -171,10 +170,15 @@ bool validateInputSize(StringRef Constraint, unsigned Size) const override; virtual bool - checkCFProtectionReturnSupported(DiagnosticsEngine &Diags) const override; + checkCFProtectionReturnSupported(DiagnosticsEngine &Diags) const override { +return true; + }; virtual bool - checkCFProtectionBranchSupported(DiagnosticsEngine &Diags) const override; + checkCFProtectionBranchSupported(DiagnosticsEngine &Diags) const override { +return true; + }; + virtual bool validateOperandSize(StringRef Constraint, unsigned Size) const; Index: lib/Basic/Targets/X86.cpp === --- lib/Basic/Targets/X86.cpp +++ lib/Basic/Targets/X86.cpp @@ -102,26 +102,6 @@ return false; } -bool X86TargetInfo::checkCFProtectionReturnSupported( -DiagnosticsEngine &Diags) const { - if (HasSHSTK) -return true; - - Diags.Report(diag::err_opt_not_valid_without_opt) << "cf-protection=return" -<< "-mshstk"; - return false; -} - -bool X86TargetInfo::checkCFProtectionBranchSupported( -DiagnosticsEngine &Diags) const { - if (HasIBT) -return true; - - Diags.Report(diag::err_opt_not_valid_without_opt) << "cf-protection=branch" -<< "-mibt"; - return false; -} - bool X86TargetInfo::initFeatureMap( llvm::StringMap &Features, DiagnosticsEngine &Diags, StringRef CPU, const std::vector &FeaturesVec) const { @@ -781,8 +761,6 @@ HasMPX = true; } else if (Feature == "+shstk") { HasSHSTK = true; -} else if (Feature == "+ibt") { - HasIBT = true; } else if (Feature == "+movbe") { HasMOVBE = true; } else if (Feature == "+sgx") { @@ -1175,8 +1153,6 @@ Builder.defineMacro("__MPX__"); if (HasSHSTK) Builder.defineMacro("__SHSTK__"); - if (HasIBT) -Builder.defineMacro("__IBT__"); if (HasSGX) Builder.defineMacro("__SGX__"); if (HasPREFETCHWT1) @@ -1394,7 +1370,6 @@ .Case("fsgsbase", HasFSGSBASE) .Case("fxsr", HasFXSR) .Case("gfni", HasGFNI) - .Case("ibt", HasIBT) .Case("lwp", HasLWP) .Case("lzcnt", HasLZCNT) .Case("mm3dnow", MMX3DNowLevel >= AMD3DNow) Index: lib/Frontend/CompilerInvocation.cpp === --- lib/Frontend/CompilerInvocation.cpp +++ lib/Frontend/CompilerInvocation.cpp @@ -2829,6 +2829,17 @@ } } + // Add the __CET__ macro if a CFProtection option is set. + if (const Arg *A = Args.getLastArg(OPT_fcf_protection_EQ)) { +StringRef Name = A->getValue(); +if (Name == "branch") + Opts.addMacroDe
[PATCH] D43016: Fix for #31362 - ms_abi is implemented incorrectly for larger values (>=16 bytes).
This revision was automatically updated to reflect the committed changes. Closed by commit rL324594: Fix for #31362 - ms_abi is implemented incorrectly for values >=16 bytes. (authored by aivchenk, committed by ). Herald added a subscriber: llvm-commits. Repository: rL LLVM https://reviews.llvm.org/D43016 Files: cfe/trunk/lib/CodeGen/TargetInfo.cpp cfe/trunk/test/CodeGen/ms_abi.c Index: cfe/trunk/test/CodeGen/ms_abi.c === --- cfe/trunk/test/CodeGen/ms_abi.c +++ cfe/trunk/test/CodeGen/ms_abi.c @@ -146,3 +146,16 @@ // WIN64: %[[AP_VAL:.*]] = load i8*, i8** %[[AP]] // WIN64-NEXT: store i8* %[[AP_VAL]], i8** %[[AP2:.*]] } + +// This test checks if structs are passed according to Win64 calling convention +// when it's enforced by __attribute((ms_abi)). +struct i128 { + unsigned long long a; + unsigned long long b; +}; + +__attribute__((ms_abi)) struct i128 f7(struct i128 a) { + // WIN64: define void @f7(%struct.i128* noalias sret %agg.result, %struct.i128* %a) + // FREEBSD: define win64cc void @f7(%struct.i128* noalias sret %agg.result, %struct.i128* %a) + return a; +} Index: cfe/trunk/lib/CodeGen/TargetInfo.cpp === --- cfe/trunk/lib/CodeGen/TargetInfo.cpp +++ cfe/trunk/lib/CodeGen/TargetInfo.cpp @@ -3529,7 +3529,17 @@ void X86_64ABIInfo::computeInfo(CGFunctionInfo &FI) const { - bool IsRegCall = FI.getCallingConvention() == llvm::CallingConv::X86_RegCall; + const unsigned CallingConv = FI.getCallingConvention(); + // It is possible to force Win64 calling convention on any x86_64 target by + // using __attribute__((ms_abi)). In such case to correctly emit Win64 + // compatible code delegate this call to WinX86_64ABIInfo::computeInfo. + if (CallingConv == llvm::CallingConv::Win64) { +WinX86_64ABIInfo Win64ABIInfo(CGT); +Win64ABIInfo.computeInfo(FI); +return; + } + + bool IsRegCall = CallingConv == llvm::CallingConv::X86_RegCall; // Keep track of the number of assigned registers. unsigned FreeIntRegs = IsRegCall ? 11 : 6; Index: cfe/trunk/test/CodeGen/ms_abi.c === --- cfe/trunk/test/CodeGen/ms_abi.c +++ cfe/trunk/test/CodeGen/ms_abi.c @@ -146,3 +146,16 @@ // WIN64: %[[AP_VAL:.*]] = load i8*, i8** %[[AP]] // WIN64-NEXT: store i8* %[[AP_VAL]], i8** %[[AP2:.*]] } + +// This test checks if structs are passed according to Win64 calling convention +// when it's enforced by __attribute((ms_abi)). +struct i128 { + unsigned long long a; + unsigned long long b; +}; + +__attribute__((ms_abi)) struct i128 f7(struct i128 a) { + // WIN64: define void @f7(%struct.i128* noalias sret %agg.result, %struct.i128* %a) + // FREEBSD: define win64cc void @f7(%struct.i128* noalias sret %agg.result, %struct.i128* %a) + return a; +} Index: cfe/trunk/lib/CodeGen/TargetInfo.cpp === --- cfe/trunk/lib/CodeGen/TargetInfo.cpp +++ cfe/trunk/lib/CodeGen/TargetInfo.cpp @@ -3529,7 +3529,17 @@ void X86_64ABIInfo::computeInfo(CGFunctionInfo &FI) const { - bool IsRegCall = FI.getCallingConvention() == llvm::CallingConv::X86_RegCall; + const unsigned CallingConv = FI.getCallingConvention(); + // It is possible to force Win64 calling convention on any x86_64 target by + // using __attribute__((ms_abi)). In such case to correctly emit Win64 + // compatible code delegate this call to WinX86_64ABIInfo::computeInfo. + if (CallingConv == llvm::CallingConv::Win64) { +WinX86_64ABIInfo Win64ABIInfo(CGT); +Win64ABIInfo.computeInfo(FI); +return; + } + + bool IsRegCall = CallingConv == llvm::CallingConv::X86_RegCall; // Keep track of the number of assigned registers. unsigned FreeIntRegs = IsRegCall ? 11 : 6; ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D43016: Fix for #31362 - ms_abi is implemented incorrectly for larger values (>=16 bytes).
This revision was automatically updated to reflect the committed changes. Closed by commit rC324594: Fix for #31362 - ms_abi is implemented incorrectly for values >=16 bytes. (authored by aivchenk, committed by ). Changed prior to commit: https://reviews.llvm.org/D43016?vs=133198&id=133395#toc Repository: rL LLVM https://reviews.llvm.org/D43016 Files: lib/CodeGen/TargetInfo.cpp test/CodeGen/ms_abi.c Index: test/CodeGen/ms_abi.c === --- test/CodeGen/ms_abi.c +++ test/CodeGen/ms_abi.c @@ -146,3 +146,16 @@ // WIN64: %[[AP_VAL:.*]] = load i8*, i8** %[[AP]] // WIN64-NEXT: store i8* %[[AP_VAL]], i8** %[[AP2:.*]] } + +// This test checks if structs are passed according to Win64 calling convention +// when it's enforced by __attribute((ms_abi)). +struct i128 { + unsigned long long a; + unsigned long long b; +}; + +__attribute__((ms_abi)) struct i128 f7(struct i128 a) { + // WIN64: define void @f7(%struct.i128* noalias sret %agg.result, %struct.i128* %a) + // FREEBSD: define win64cc void @f7(%struct.i128* noalias sret %agg.result, %struct.i128* %a) + return a; +} Index: lib/CodeGen/TargetInfo.cpp === --- lib/CodeGen/TargetInfo.cpp +++ lib/CodeGen/TargetInfo.cpp @@ -3529,7 +3529,17 @@ void X86_64ABIInfo::computeInfo(CGFunctionInfo &FI) const { - bool IsRegCall = FI.getCallingConvention() == llvm::CallingConv::X86_RegCall; + const unsigned CallingConv = FI.getCallingConvention(); + // It is possible to force Win64 calling convention on any x86_64 target by + // using __attribute__((ms_abi)). In such case to correctly emit Win64 + // compatible code delegate this call to WinX86_64ABIInfo::computeInfo. + if (CallingConv == llvm::CallingConv::Win64) { +WinX86_64ABIInfo Win64ABIInfo(CGT); +Win64ABIInfo.computeInfo(FI); +return; + } + + bool IsRegCall = CallingConv == llvm::CallingConv::X86_RegCall; // Keep track of the number of assigned registers. unsigned FreeIntRegs = IsRegCall ? 11 : 6; Index: test/CodeGen/ms_abi.c === --- test/CodeGen/ms_abi.c +++ test/CodeGen/ms_abi.c @@ -146,3 +146,16 @@ // WIN64: %[[AP_VAL:.*]] = load i8*, i8** %[[AP]] // WIN64-NEXT: store i8* %[[AP_VAL]], i8** %[[AP2:.*]] } + +// This test checks if structs are passed according to Win64 calling convention +// when it's enforced by __attribute((ms_abi)). +struct i128 { + unsigned long long a; + unsigned long long b; +}; + +__attribute__((ms_abi)) struct i128 f7(struct i128 a) { + // WIN64: define void @f7(%struct.i128* noalias sret %agg.result, %struct.i128* %a) + // FREEBSD: define win64cc void @f7(%struct.i128* noalias sret %agg.result, %struct.i128* %a) + return a; +} Index: lib/CodeGen/TargetInfo.cpp === --- lib/CodeGen/TargetInfo.cpp +++ lib/CodeGen/TargetInfo.cpp @@ -3529,7 +3529,17 @@ void X86_64ABIInfo::computeInfo(CGFunctionInfo &FI) const { - bool IsRegCall = FI.getCallingConvention() == llvm::CallingConv::X86_RegCall; + const unsigned CallingConv = FI.getCallingConvention(); + // It is possible to force Win64 calling convention on any x86_64 target by + // using __attribute__((ms_abi)). In such case to correctly emit Win64 + // compatible code delegate this call to WinX86_64ABIInfo::computeInfo. + if (CallingConv == llvm::CallingConv::Win64) { +WinX86_64ABIInfo Win64ABIInfo(CGT); +Win64ABIInfo.computeInfo(FI); +return; + } + + bool IsRegCall = CallingConv == llvm::CallingConv::X86_RegCall; // Keep track of the number of assigned registers. unsigned FreeIntRegs = IsRegCall ? 11 : 6; ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D43814: [x86][CET] Introduce _get_ssp, _inc_ssp intrinsics
This revision was automatically updated to reflect the committed changes. Closed by commit rC326689: [x86][CET] Introduce _get_ssp, _inc_ssp intrinsics (authored by aivchenk, committed by ). Repository: rC Clang https://reviews.llvm.org/D43814 Files: lib/Headers/cetintrin.h test/CodeGen/cetintrin.c Index: test/CodeGen/cetintrin.c === --- test/CodeGen/cetintrin.c +++ test/CodeGen/cetintrin.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -ffreestanding %s -triple=i386-apple-darwin -target-feature +shstk -emit-llvm -o - -Wall -Werror | FileCheck %s -// RUN: %clang_cc1 -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +shstk -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefix=X86_64 +// RUN: %clang_cc1 -ffreestanding %s -triple=i386-apple-darwin -target-feature +shstk -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefix=I386 --check-prefix=CHECK +// RUN: %clang_cc1 -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +shstk -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefix=X86_64 --check-prefix=CHECK #include @@ -15,6 +15,20 @@ // X86_64: call void @llvm.x86.incsspq(i64 %{{[a-z0-9.]+}}) _incsspq(a); } + +void test_inc_ssp(unsigned int a) { + // X86_64-LABEL: @test_inc_ssp + // X86_64: call void @llvm.x86.incsspq(i64 %{{[a-z0-9.]+}}) + _inc_ssp(a); +} +#else + +void test_inc_ssp(unsigned int a) { + // I386-LABEL: @test_inc_ssp + // I386: call void @llvm.x86.incsspd(i32 %{{[0-9]+}}) + _inc_ssp(a); +} + #endif unsigned int test_rdsspd(unsigned int a) { @@ -29,6 +43,21 @@ // X86_64: call i64 @llvm.x86.rdsspq(i64 %{{[a-z0-9.]+}}) return _rdsspq(a); } + +unsigned long long test_get_ssp(void) { + // X86_64-LABEL: @test_get_ssp + // X86_64: call i64 @llvm.x86.rdsspq(i64 0) + return _get_ssp(); +} + +#else + +unsigned int test_get_ssp(void) { + // I386-LABEL: @test_get_ssp + // I386: call i32 @llvm.x86.rdsspd(i32 0) + return _get_ssp(); +} + #endif void test_saveprevssp() { Index: lib/Headers/cetintrin.h === --- lib/Headers/cetintrin.h +++ lib/Headers/cetintrin.h @@ -42,6 +42,16 @@ } #endif /* __x86_64__ */ +#ifdef __x86_64__ +static __inline__ void __DEFAULT_FN_ATTRS _inc_ssp(unsigned int __a) { + __builtin_ia32_incsspq(__a); +} +#else /* __x86_64__ */ +static __inline__ void __DEFAULT_FN_ATTRS _inc_ssp(unsigned int __a) { + __builtin_ia32_incsspd((int)__a); +} +#endif /* __x86_64__ */ + static __inline__ unsigned int __DEFAULT_FN_ATTRS _rdsspd(unsigned int __a) { return __builtin_ia32_rdsspd(__a); } @@ -52,6 +62,16 @@ } #endif /* __x86_64__ */ +#ifdef __x86_64__ +static __inline__ unsigned long long __DEFAULT_FN_ATTRS _get_ssp(void) { + return __builtin_ia32_rdsspq(0); +} +#else /* __x86_64__ */ +static __inline__ unsigned int __DEFAULT_FN_ATTRS _get_ssp(void) { + return __builtin_ia32_rdsspd(0); +} +#endif /* __x86_64__ */ + static __inline__ void __DEFAULT_FN_ATTRS _saveprevssp() { __builtin_ia32_saveprevssp(); } Index: test/CodeGen/cetintrin.c === --- test/CodeGen/cetintrin.c +++ test/CodeGen/cetintrin.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -ffreestanding %s -triple=i386-apple-darwin -target-feature +shstk -emit-llvm -o - -Wall -Werror | FileCheck %s -// RUN: %clang_cc1 -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +shstk -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefix=X86_64 +// RUN: %clang_cc1 -ffreestanding %s -triple=i386-apple-darwin -target-feature +shstk -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefix=I386 --check-prefix=CHECK +// RUN: %clang_cc1 -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +shstk -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefix=X86_64 --check-prefix=CHECK #include @@ -15,6 +15,20 @@ // X86_64: call void @llvm.x86.incsspq(i64 %{{[a-z0-9.]+}}) _incsspq(a); } + +void test_inc_ssp(unsigned int a) { + // X86_64-LABEL: @test_inc_ssp + // X86_64: call void @llvm.x86.incsspq(i64 %{{[a-z0-9.]+}}) + _inc_ssp(a); +} +#else + +void test_inc_ssp(unsigned int a) { + // I386-LABEL: @test_inc_ssp + // I386: call void @llvm.x86.incsspd(i32 %{{[0-9]+}}) + _inc_ssp(a); +} + #endif unsigned int test_rdsspd(unsigned int a) { @@ -29,6 +43,21 @@ // X86_64: call i64 @llvm.x86.rdsspq(i64 %{{[a-z0-9.]+}}) return _rdsspq(a); } + +unsigned long long test_get_ssp(void) { + // X86_64-LABEL: @test_get_ssp + // X86_64: call i64 @llvm.x86.rdsspq(i64 0) + return _get_ssp(); +} + +#else + +unsigned int test_get_ssp(void) { + // I386-LABEL: @test_get_ssp + // I386: call i32 @llvm.x86.rdsspd(i32 0) + return _get_ssp(); +} + #endif void test_saveprevssp() { Index: lib/Headers/cetintrin.h ===
[PATCH] D44786: Lowering x86 adds/addus/subs/subus intrinsics (clang)
This revision was automatically updated to reflect the committed changes. Closed by commit rL330323: Lowering x86 adds/addus/subs/subus intrinsics (clang) (authored by aivchenk, committed by ). Herald added a subscriber: llvm-commits. Repository: rL LLVM https://reviews.llvm.org/D44786 Files: cfe/trunk/lib/CodeGen/CGBuiltin.cpp cfe/trunk/test/CodeGen/avx2-builtins.c cfe/trunk/test/CodeGen/avx512bw-builtins.c cfe/trunk/test/CodeGen/avx512vlbw-builtins.c cfe/trunk/test/CodeGen/sse2-builtins.c Index: cfe/trunk/test/CodeGen/avx2-builtins.c === --- cfe/trunk/test/CodeGen/avx2-builtins.c +++ cfe/trunk/test/CodeGen/avx2-builtins.c @@ -56,25 +56,53 @@ __m256i test_mm256_adds_epi8(__m256i a, __m256i b) { // CHECK-LABEL: test_mm256_adds_epi8 - // CHECK: call <32 x i8> @llvm.x86.avx2.padds.b(<32 x i8> %{{.*}}, <32 x i8> %{{.*}}) + // CHECK-NOT: call <32 x i8> @llvm.x86.avx2.padds.b(<32 x i8> %{{.*}}, <32 x i8> %{{.*}}) + // CHECK: sext <32 x i8> %{{.*}} to <32 x i16> + // CHECK: sext <32 x i8> %{{.*}} to <32 x i16> + // CHECK: add <32 x i16> %{{.*}}, %{{.*}} + // CHECK: icmp sle <32 x i16> %{{.*}}, + // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> + // CHECK: icmp slt <32 x i16> %{{.*}}, + // CHECK: select <32 x i1> %{{.*}}, <32 x i16> , <32 x i16> %{{.*}} + // CHECK: trunc <32 x i16> %{{.*}} to <32 x i8> return _mm256_adds_epi8(a, b); } __m256i test_mm256_adds_epi16(__m256i a, __m256i b) { // CHECK-LABEL: test_mm256_adds_epi16 - // CHECK: call <16 x i16> @llvm.x86.avx2.padds.w(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}) + // CHECK-NOT: call <16 x i16> @llvm.x86.avx2.padds.w(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}) + // CHECK: sext <16 x i16> %{{.*}} to <16 x i32> + // CHECK: sext <16 x i16> %{{.*}} to <16 x i32> + // CHECK: add <16 x i32> %{{.*}}, %{{.*}} + // CHECK: icmp sle <16 x i32> %{{.*}}, + // CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> + // CHECK: icmp slt <16 x i32> %{{.*}}, + // CHECK: select <16 x i1> %{{.*}}, <16 x i32> , <16 x i32> %{{.*}} + // CHECK: trunc <16 x i32> %{{.*}} to <16 x i16> return _mm256_adds_epi16(a, b); } __m256i test_mm256_adds_epu8(__m256i a, __m256i b) { // CHECK-LABEL: test_mm256_adds_epu8 - // CHECK: call <32 x i8> @llvm.x86.avx2.paddus.b(<32 x i8> %{{.*}}, <32 x i8> %{{.*}}) + // CHECK-NOT: call <32 x i8> @llvm.x86.avx2.paddus.b(<32 x i8> %{{.*}}, <32 x i8> %{{.*}}) + // CHECK: zext <32 x i8> %{{.*}} to <32 x i16> + // CHECK: zext <32 x i8> %{{.*}} to <32 x i16> + // CHECK: add <32 x i16> %{{.*}}, %{{.*}} + // CHECK: icmp ule <32 x i16> %{{.*}}, + // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> + // CHECK: trunc <32 x i16> %{{.*}} to <32 x i8> return _mm256_adds_epu8(a, b); } __m256i test_mm256_adds_epu16(__m256i a, __m256i b) { // CHECK-LABEL: test_mm256_adds_epu16 - // CHECK: call <16 x i16> @llvm.x86.avx2.paddus.w(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}) + // CHECK-NOT: call <16 x i16> @llvm.x86.avx2.paddus.w(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}) + // CHECK: zext <16 x i16> %{{.*}} to <16 x i32> + // CHECK: zext <16 x i16> %{{.*}} to <16 x i32> + // CHECK: add <16 x i32> %{{.*}}, %{{.*}} + // CHECK: icmp ule <16 x i32> %{{.*}}, + // CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> + // CHECK: trunc <16 x i32> %{{.*}} to <16 x i16> return _mm256_adds_epu16(a, b); } @@ -1171,25 +1199,47 @@ __m256i test_mm256_subs_epi8(__m256i a, __m256i b) { // CHECK-LABEL: test_mm256_subs_epi8 - // CHECK: call <32 x i8> @llvm.x86.avx2.psubs.b(<32 x i8> %{{.*}}, <32 x i8> %{{.*}}) + // CHECK-NOT: call <32 x i8> @llvm.x86.avx2.psubs.b(<32 x i8> %{{.*}}, <32 x i8> %{{.*}}) + // CHECK: sext <32 x i8> %{{.*}} to <32 x i16> + // CHECK: sext <32 x i8> %{{.*}} to <32 x i16> + // CHECK: sub <32 x i16> %{{.*}}, %{{.*}} + // CHECK: icmp sle <32 x i16> %{{.*}}, + // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> + // CHECK: icmp slt <32 x i16> %{{.*}}, + // CHECK: select <32 x i1> %{{.*}}, <32 x i16> , <32 x i16> %{{.*}} + // CHECK: trunc <32 x i16> %{{.*}} to <32 x i8> return _mm256_subs_epi8(a, b); } __m256i test_mm256_subs_epi16(__m256i a, __m256i b) { // CHECK-LABEL: test_mm256_subs_epi16 - // CHECK: call <16 x i16> @llvm.x86.avx2.psubs.w(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}) + // CHECK-NOT: call <16 x i16> @llvm.x86.avx2.psubs.w(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}) + // CHECK: sext <16 x i16> %{{.*}} to <16 x i32> + // CHECK: sext <16 x i16> %{{.*}} to <16 x i32> + // CHECK: sub <16 x i32> %{{.*}}, %{{.*}} + // CHECK: icmp sle <16 x i32> %{{.*}}, + // CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> + // CHECK: icmp slt <16 x i32> %{{.*}}, + // CHECK: select <16 x i1> %{{.*}}, <16 x i32> , <16 x i32> %{{.*}} + // CHECK: trunc <16 x i32> %{{.*}} to <16 x i16> return _mm256_subs_epi16(a, b