From: Sanjay Patel Date: Thu, 16 Jun 2016 18:45:01 +0000 (+0000) Subject: [x86] generate IR for AVX2 integer min/max builtins X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=191558e10b7831cdb7e8a2b16c4fd8d5146e57b5;p=clang [x86] generate IR for AVX2 integer min/max builtins Sibling patch to r272932: http://reviews.llvm.org/rL272932 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@272933 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp index 8b8996bde9..4cc0560de3 100644 --- a/lib/CodeGen/CGBuiltin.cpp +++ b/lib/CodeGen/CGBuiltin.cpp @@ -6826,28 +6826,40 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID, case X86::BI__builtin_ia32_pcmpgtq512_mask: return EmitX86MaskedCompare(*this, ICmpInst::ICMP_SGT, Ops); - // TODO: Handle 64/256/512-bit vector widths of min/max. + // TODO: Handle 64/512-bit vector widths of min/max. case X86::BI__builtin_ia32_pmaxsb128: case X86::BI__builtin_ia32_pmaxsw128: - case X86::BI__builtin_ia32_pmaxsd128: { + case X86::BI__builtin_ia32_pmaxsd128: + case X86::BI__builtin_ia32_pmaxsb256: + case X86::BI__builtin_ia32_pmaxsw256: + case X86::BI__builtin_ia32_pmaxsd256: { Value *Cmp = Builder.CreateICmp(ICmpInst::ICMP_SGT, Ops[0], Ops[1]); return Builder.CreateSelect(Cmp, Ops[0], Ops[1]); } case X86::BI__builtin_ia32_pmaxub128: case X86::BI__builtin_ia32_pmaxuw128: - case X86::BI__builtin_ia32_pmaxud128: { + case X86::BI__builtin_ia32_pmaxud128: + case X86::BI__builtin_ia32_pmaxub256: + case X86::BI__builtin_ia32_pmaxuw256: + case X86::BI__builtin_ia32_pmaxud256: { Value *Cmp = Builder.CreateICmp(ICmpInst::ICMP_UGT, Ops[0], Ops[1]); return Builder.CreateSelect(Cmp, Ops[0], Ops[1]); } case X86::BI__builtin_ia32_pminsb128: case X86::BI__builtin_ia32_pminsw128: - case X86::BI__builtin_ia32_pminsd128: { + case X86::BI__builtin_ia32_pminsd128: + case X86::BI__builtin_ia32_pminsb256: + case X86::BI__builtin_ia32_pminsw256: + case X86::BI__builtin_ia32_pminsd256: { Value *Cmp = Builder.CreateICmp(ICmpInst::ICMP_SLT, Ops[0], Ops[1]); return Builder.CreateSelect(Cmp, Ops[0], Ops[1]); } case X86::BI__builtin_ia32_pminub128: case X86::BI__builtin_ia32_pminuw128: - case X86::BI__builtin_ia32_pminud128: { + case X86::BI__builtin_ia32_pminud128: + case X86::BI__builtin_ia32_pminub256: + case X86::BI__builtin_ia32_pminuw256: + case X86::BI__builtin_ia32_pminud256: { Value *Cmp = Builder.CreateICmp(ICmpInst::ICMP_ULT, Ops[0], Ops[1]); return Builder.CreateSelect(Cmp, Ops[0], Ops[1]); } diff --git a/test/CodeGen/avx2-builtins.c b/test/CodeGen/avx2-builtins.c index f1af9aeda9..db3c40a321 100644 --- a/test/CodeGen/avx2-builtins.c +++ b/test/CodeGen/avx2-builtins.c @@ -717,73 +717,85 @@ void test_mm256_maskstore_epi64(long long *a, __m256i m, __m256i b) { __m256i test_mm256_max_epi8(__m256i a, __m256i b) { // CHECK-LABEL: test_mm256_max_epi8 - // CHECK: call <32 x i8> @llvm.x86.avx2.pmaxs.b(<32 x i8> %{{.*}}, <32 x i8> %{{.*}}) + // CHECK: [[CMP:%.*]] = icmp sgt <32 x i8> [[X:%.*]], [[Y:%.*]] + // CHECK-NEXT: select <32 x i1> [[CMP]], <32 x i8> [[X]], <32 x i8> [[Y]] return _mm256_max_epi8(a, b); } __m256i test_mm256_max_epi16(__m256i a, __m256i b) { // CHECK-LABEL: test_mm256_max_epi16 - // CHECK: call <16 x i16> @llvm.x86.avx2.pmaxs.w(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}) + // CHECK: [[CMP:%.*]] = icmp sgt <16 x i16> [[X:%.*]], [[Y:%.*]] + // CHECK-NEXT: select <16 x i1> [[CMP]], <16 x i16> [[X]], <16 x i16> [[Y]] return _mm256_max_epi16(a, b); } __m256i test_mm256_max_epi32(__m256i a, __m256i b) { // CHECK-LABEL: test_mm256_max_epi32 - // CHECK: call <8 x i32> @llvm.x86.avx2.pmaxs.d(<8 x i32> %{{.*}}, <8 x i32> %{{.*}}) + // CHECK: [[CMP:%.*]] = icmp sgt <8 x i32> [[X:%.*]], [[Y:%.*]] + // CHECK-NEXT: select <8 x i1> [[CMP]], <8 x i32> [[X]], <8 x i32> [[Y]] return _mm256_max_epi32(a, b); } __m256i test_mm256_max_epu8(__m256i a, __m256i b) { // CHECK-LABEL: test_mm256_max_epu8 - // CHECK: call <32 x i8> @llvm.x86.avx2.pmaxu.b(<32 x i8> %{{.*}}, <32 x i8> %{{.*}}) + // CHECK: [[CMP:%.*]] = icmp ugt <32 x i8> [[X:%.*]], [[Y:%.*]] + // CHECK-NEXT: select <32 x i1> [[CMP]], <32 x i8> [[X]], <32 x i8> [[Y]] return _mm256_max_epu8(a, b); } __m256i test_mm256_max_epu16(__m256i a, __m256i b) { // CHECK-LABEL: test_mm256_max_epu16 - // CHECK: call <16 x i16> @llvm.x86.avx2.pmaxu.w(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}) + // CHECK: [[CMP:%.*]] = icmp ugt <16 x i16> [[X:%.*]], [[Y:%.*]] + // CHECK-NEXT: select <16 x i1> [[CMP]], <16 x i16> [[X]], <16 x i16> [[Y]] return _mm256_max_epu16(a, b); } __m256i test_mm256_max_epu32(__m256i a, __m256i b) { // CHECK-LABEL: test_mm256_max_epu32 - // CHECK: call <8 x i32> @llvm.x86.avx2.pmaxu.d(<8 x i32> %{{.*}}, <8 x i32> %{{.*}}) + // CHECK: [[CMP:%.*]] = icmp ugt <8 x i32> [[X:%.*]], [[Y:%.*]] + // CHECK-NEXT: select <8 x i1> [[CMP]], <8 x i32> [[X]], <8 x i32> [[Y]] return _mm256_max_epu32(a, b); } __m256i test_mm256_min_epi8(__m256i a, __m256i b) { // CHECK-LABEL: test_mm256_min_epi8 - // CHECK: call <32 x i8> @llvm.x86.avx2.pmins.b(<32 x i8> %{{.*}}, <32 x i8> %{{.*}}) + // CHECK: [[CMP:%.*]] = icmp slt <32 x i8> [[X:%.*]], [[Y:%.*]] + // CHECK-NEXT: select <32 x i1> [[CMP]], <32 x i8> [[X]], <32 x i8> [[Y]] return _mm256_min_epi8(a, b); } __m256i test_mm256_min_epi16(__m256i a, __m256i b) { // CHECK-LABEL: test_mm256_min_epi16 - // CHECK: call <16 x i16> @llvm.x86.avx2.pmins.w(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}) + // CHECK: [[CMP:%.*]] = icmp slt <16 x i16> [[X:%.*]], [[Y:%.*]] + // CHECK-NEXT: select <16 x i1> [[CMP]], <16 x i16> [[X]], <16 x i16> [[Y]] return _mm256_min_epi16(a, b); } __m256i test_mm256_min_epi32(__m256i a, __m256i b) { // CHECK-LABEL: test_mm256_min_epi32 - // CHECK: call <8 x i32> @llvm.x86.avx2.pmins.d(<8 x i32> %{{.*}}, <8 x i32> %{{.*}}) + // CHECK: [[CMP:%.*]] = icmp slt <8 x i32> [[X:%.*]], [[Y:%.*]] + // CHECK-NEXT: select <8 x i1> [[CMP]], <8 x i32> [[X]], <8 x i32> [[Y]] return _mm256_min_epi32(a, b); } __m256i test_mm256_min_epu8(__m256i a, __m256i b) { // CHECK-LABEL: test_mm256_min_epu8 - // CHECK: call <32 x i8> @llvm.x86.avx2.pminu.b(<32 x i8> %{{.*}}, <32 x i8> %{{.*}}) + // CHECK: [[CMP:%.*]] = icmp ult <32 x i8> [[X:%.*]], [[Y:%.*]] + // CHECK-NEXT: select <32 x i1> [[CMP]], <32 x i8> [[X]], <32 x i8> [[Y]] return _mm256_min_epu8(a, b); } __m256i test_mm256_min_epu16(__m256i a, __m256i b) { // CHECK-LABEL: test_mm256_min_epu16 - // CHECK: call <16 x i16> @llvm.x86.avx2.pminu.w(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}) + // CHECK: [[CMP:%.*]] = icmp ult <16 x i16> [[X:%.*]], [[Y:%.*]] + // CHECK-NEXT: select <16 x i1> [[CMP]], <16 x i16> [[X]], <16 x i16> [[Y]] return _mm256_min_epu16(a, b); } __m256i test_mm256_min_epu32(__m256i a, __m256i b) { // CHECK-LABEL: test_mm256_min_epu32 - // CHECK: call <8 x i32> @llvm.x86.avx2.pminu.d(<8 x i32> %{{.*}}, <8 x i32> %{{.*}}) + // CHECK: [[CMP:%.*]] = icmp ult <8 x i32> [[X:%.*]], [[Y:%.*]] + // CHECK-NEXT: select <8 x i1> [[CMP]], <8 x i32> [[X]], <8 x i32> [[Y]] return _mm256_min_epu32(a, b); }