181 changes: 16 additions & 165 deletions clang/test/CodeGen/X86/avx512-reduceIntrin.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,261 +4,112 @@

long long test_mm512_reduce_add_epi64(__m512i __W){
// CHECK-LABEL: @test_mm512_reduce_add_epi64(
// CHECK: shufflevector <8 x i64> %{{.*}}, <8 x i64> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
// CHECK: shufflevector <8 x i64> %{{.*}}, <8 x i64> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
// CHECK: add <4 x i64> %{{.*}}, %{{.*}}
// CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> undef, <2 x i32> <i32 0, i32 1>
// CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> undef, <2 x i32> <i32 2, i32 3>
// CHECK: add <2 x i64> %{{.*}}, %{{.*}}
// CHECK: shufflevector <2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <2 x i32> <i32 1, i32 0>
// CHECK: add <2 x i64> %{{.*}}, %{{.*}}
// CHECK: extractelement <2 x i64> %{{.*}}, i32 0
// CHECK: call i64 @llvm.vector.reduce.add.v8i64(<8 x i64> %{{.*}})
return _mm512_reduce_add_epi64(__W);
}

long long test_mm512_reduce_mul_epi64(__m512i __W){
// CHECK-LABEL: @test_mm512_reduce_mul_epi64(
// CHECK: shufflevector <8 x i64> %{{.*}}, <8 x i64> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
// CHECK: shufflevector <8 x i64> %{{.*}}, <8 x i64> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
// CHECK: mul <4 x i64> %{{.*}}, %{{.*}}
// CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> undef, <2 x i32> <i32 0, i32 1>
// CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> undef, <2 x i32> <i32 2, i32 3>
// CHECK: mul <2 x i64> %{{.*}}, %{{.*}}
// CHECK: shufflevector <2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <2 x i32> <i32 1, i32 0>
// CHECK: mul <2 x i64> %{{.*}}, %{{.*}}
// CHECK: extractelement <2 x i64> %{{.*}}, i32 0
// CHECK: call i64 @llvm.vector.reduce.mul.v8i64(<8 x i64> %{{.*}})
return _mm512_reduce_mul_epi64(__W);
}

long long test_mm512_reduce_or_epi64(__m512i __W){
// CHECK-LABEL: @test_mm512_reduce_or_epi64(
// CHECK: shufflevector <8 x i64> %{{.*}}, <8 x i64> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
// CHECK: shufflevector <8 x i64> %{{.*}}, <8 x i64> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
// CHECK: or <4 x i64> %{{.*}}, %{{.*}}
// CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> undef, <2 x i32> <i32 0, i32 1>
// CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> undef, <2 x i32> <i32 2, i32 3>
// CHECK: or <2 x i64> %{{.*}}, %{{.*}}
// CHECK: shufflevector <2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <2 x i32> <i32 1, i32 0>
// CHECK: or <2 x i64> %{{.*}}, %{{.*}}
// CHECK: extractelement <2 x i64> %{{.*}}, i32 0
// CHECK: call i64 @llvm.vector.reduce.or.v8i64(<8 x i64> %{{.*}})
return _mm512_reduce_or_epi64(__W);
}

long long test_mm512_reduce_and_epi64(__m512i __W){
// CHECK-LABEL: @test_mm512_reduce_and_epi64(
// CHECK: shufflevector <8 x i64> %{{.*}}, <8 x i64> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
// CHECK: shufflevector <8 x i64> %{{.*}}, <8 x i64> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
// CHECK: and <4 x i64> %{{.*}}, %{{.*}}
// CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> undef, <2 x i32> <i32 0, i32 1>
// CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> undef, <2 x i32> <i32 2, i32 3>
// CHECK: and <2 x i64> %{{.*}}, %{{.*}}
// CHECK: shufflevector <2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <2 x i32> <i32 1, i32 0>
// CHECK: and <2 x i64> %{{.*}}, %{{.*}}
// CHECK: extractelement <2 x i64> %{{.*}}, i32 0
// CHECK: call i64 @llvm.vector.reduce.and.v8i64(<8 x i64> %{{.*}})
return _mm512_reduce_and_epi64(__W);
}

long long test_mm512_mask_reduce_add_epi64(__mmask8 __M, __m512i __W){
// CHECK-LABEL: @test_mm512_mask_reduce_add_epi64(
// CHECK: bitcast i8 %{{.*}} to <8 x i1>
// CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}}
// CHECK: shufflevector <8 x i64> %{{.*}}, <8 x i64> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
// CHECK: shufflevector <8 x i64> %{{.*}}, <8 x i64> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
// CHECK: add <4 x i64> %{{.*}}, %{{.*}}
// CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> undef, <2 x i32> <i32 0, i32 1>
// CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> undef, <2 x i32> <i32 2, i32 3>
// CHECK: add <2 x i64> %{{.*}}, %{{.*}}
// CHECK: shufflevector <2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <2 x i32> <i32 1, i32 0>
// CHECK: add <2 x i64> %{{.*}}, %{{.*}}
// CHECK: extractelement <2 x i64> %{{.*}}, i32 0
// CHECK: call i64 @llvm.vector.reduce.add.v8i64(<8 x i64> %{{.*}})
return _mm512_mask_reduce_add_epi64(__M, __W);
}

long long test_mm512_mask_reduce_mul_epi64(__mmask8 __M, __m512i __W){
// CHECK-LABEL: @test_mm512_mask_reduce_mul_epi64(
// CHECK: bitcast i8 %{{.*}} to <8 x i1>
// CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}}
// CHECK: shufflevector <8 x i64> %{{.*}}, <8 x i64> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
// CHECK: shufflevector <8 x i64> %{{.*}}, <8 x i64> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
// CHECK: mul <4 x i64> %{{.*}}, %{{.*}}
// CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> undef, <2 x i32> <i32 0, i32 1>
// CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> undef, <2 x i32> <i32 2, i32 3>
// CHECK: mul <2 x i64> %{{.*}}, %{{.*}}
// CHECK: shufflevector <2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <2 x i32> <i32 1, i32 0>
// CHECK: mul <2 x i64> %{{.*}}, %{{.*}}
// CHECK: extractelement <2 x i64> %{{.*}}, i32 0
// CHECK: call i64 @llvm.vector.reduce.mul.v8i64(<8 x i64> %{{.*}})
return _mm512_mask_reduce_mul_epi64(__M, __W);
}

long long test_mm512_mask_reduce_and_epi64(__mmask8 __M, __m512i __W){
// CHECK-LABEL: @test_mm512_mask_reduce_and_epi64(
// CHECK: bitcast i8 %{{.*}} to <8 x i1>
// CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}}
// CHECK: shufflevector <8 x i64> %{{.*}}, <8 x i64> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
// CHECK: shufflevector <8 x i64> %{{.*}}, <8 x i64> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
// CHECK: and <4 x i64> %{{.*}}, %{{.*}}
// CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> undef, <2 x i32> <i32 0, i32 1>
// CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> undef, <2 x i32> <i32 2, i32 3>
// CHECK: and <2 x i64> %{{.*}}, %{{.*}}
// CHECK: shufflevector <2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <2 x i32> <i32 1, i32 0>
// CHECK: and <2 x i64> %{{.*}}, %{{.*}}
// CHECK: extractelement <2 x i64> %{{.*}}, i32 0
// CHECK: call i64 @llvm.vector.reduce.and.v8i64(<8 x i64> %{{.*}})
return _mm512_mask_reduce_and_epi64(__M, __W);
}

long long test_mm512_mask_reduce_or_epi64(__mmask8 __M, __m512i __W){
// CHECK-LABEL: @test_mm512_mask_reduce_or_epi64(
// CHECK: bitcast i8 %{{.*}} to <8 x i1>
// CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}}
// CHECK: shufflevector <8 x i64> %{{.*}}, <8 x i64> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
// CHECK: shufflevector <8 x i64> %{{.*}}, <8 x i64> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
// CHECK: or <4 x i64> %{{.*}}, %{{.*}}
// CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> undef, <2 x i32> <i32 0, i32 1>
// CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> undef, <2 x i32> <i32 2, i32 3>
// CHECK: or <2 x i64> %{{.*}}, %{{.*}}
// CHECK: shufflevector <2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <2 x i32> <i32 1, i32 0>
// CHECK: or <2 x i64> %{{.*}}, %{{.*}}
// CHECK: extractelement <2 x i64> %{{.*}}, i32 0
// CHECK: call i64 @llvm.vector.reduce.or.v8i64(<8 x i64> %{{.*}})
return _mm512_mask_reduce_or_epi64(__M, __W);
}

int test_mm512_reduce_add_epi32(__m512i __W){
// CHECK-LABEL: @test_mm512_reduce_add_epi32(
// CHECK: shufflevector <8 x i64> %{{.*}}, <8 x i64> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
// CHECK: shufflevector <8 x i64> %{{.*}}, <8 x i64> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
// CHECK: add <8 x i32> %{{.*}}, %{{.*}}
// CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> undef, <2 x i32> <i32 0, i32 1>
// CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> undef, <2 x i32> <i32 2, i32 3>
// CHECK: add <4 x i32> %{{.*}}, %{{.*}}
// CHECK: shufflevector <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> <i32 2, i32 3, i32 0, i32 1>
// CHECK: add <4 x i32> %{{.*}}, %{{.*}}
// CHECK: shufflevector <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> <i32 1, i32 0, i32 3, i32 2>
// CHECK: add <4 x i32> %{{.*}}, %{{.*}}
// CHECK: extractelement <4 x i32> %{{.*}}, i32 0
// CHECK: call i32 @llvm.vector.reduce.add.v16i32(<16 x i32> %{{.*}})
return _mm512_reduce_add_epi32(__W);
}

int test_mm512_reduce_mul_epi32(__m512i __W){
// CHECK-LABEL: @test_mm512_reduce_mul_epi32(
// CHECK: shufflevector <8 x i64> %{{.*}}, <8 x i64> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
// CHECK: shufflevector <8 x i64> %{{.*}}, <8 x i64> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
// CHECK: mul <8 x i32> %{{.*}}, %{{.*}}
// CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> undef, <2 x i32> <i32 0, i32 1>
// CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> undef, <2 x i32> <i32 2, i32 3>
// CHECK: mul <4 x i32> %{{.*}}, %{{.*}}
// CHECK: shufflevector <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> <i32 2, i32 3, i32 0, i32 1>
// CHECK: mul <4 x i32> %{{.*}}, %{{.*}}
// CHECK: shufflevector <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> <i32 1, i32 0, i32 3, i32 2>
// CHECK: mul <4 x i32> %{{.*}}, %{{.*}}
// CHECK: extractelement <4 x i32> %{{.*}}, i32 0
// CHECK: call i32 @llvm.vector.reduce.mul.v16i32(<16 x i32> %{{.*}})
return _mm512_reduce_mul_epi32(__W);
}

int test_mm512_reduce_or_epi32(__m512i __W){
// CHECK-LABEL: @test_mm512_reduce_or_epi32(
// CHECK: shufflevector <8 x i64> %{{.*}}, <8 x i64> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
// CHECK: shufflevector <8 x i64> %{{.*}}, <8 x i64> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
// CHECK: or <8 x i32> %{{.*}}, %{{.*}}
// CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> undef, <2 x i32> <i32 0, i32 1>
// CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> undef, <2 x i32> <i32 2, i32 3>
// CHECK: or <4 x i32> %{{.*}}, %{{.*}}
// CHECK: shufflevector <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> <i32 2, i32 3, i32 0, i32 1>
// CHECK: or <4 x i32> %{{.*}}, %{{.*}}
// CHECK: shufflevector <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> <i32 1, i32 0, i32 3, i32 2>
// CHECK: or <4 x i32> %{{.*}}, %{{.*}}
// CHECK: extractelement <4 x i32> %{{.*}}, i32 0
// CHECK: call i32 @llvm.vector.reduce.or.v16i32(<16 x i32> %{{.*}})
return _mm512_reduce_or_epi32(__W);
}

int test_mm512_reduce_and_epi32(__m512i __W){
// CHECK-LABEL: @test_mm512_reduce_and_epi32(
// CHECK: shufflevector <8 x i64> %{{.*}}, <8 x i64> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
// CHECK: shufflevector <8 x i64> %{{.*}}, <8 x i64> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
// CHECK: and <8 x i32> %{{.*}}, %{{.*}}
// CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> undef, <2 x i32> <i32 0, i32 1>
// CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> undef, <2 x i32> <i32 2, i32 3>
// CHECK: and <4 x i32> %{{.*}}, %{{.*}}
// CHECK: shufflevector <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> <i32 2, i32 3, i32 0, i32 1>
// CHECK: and <4 x i32> %{{.*}}, %{{.*}}
// CHECK: shufflevector <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> <i32 1, i32 0, i32 3, i32 2>
// CHECK: and <4 x i32> %{{.*}}, %{{.*}}
// CHECK: extractelement <4 x i32> %{{.*}}, i32 0
// CHECK: call i32 @llvm.vector.reduce.and.v16i32(<16 x i32> %{{.*}})
return _mm512_reduce_and_epi32(__W);
}

int test_mm512_mask_reduce_add_epi32(__mmask16 __M, __m512i __W){
// CHECK-LABEL: @test_mm512_mask_reduce_add_epi32(
// CHECK: bitcast i16 %{{.*}} to <16 x i1>
// CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}}
// CHECK: bitcast <16 x i32> %{{.*}} to <8 x i64>
// CHECK: shufflevector <8 x i64> %{{.*}}, <8 x i64> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
// CHECK: shufflevector <8 x i64> %{{.*}}, <8 x i64> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
// CHECK: add <8 x i32> %{{.*}}, %{{.*}}
// CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> undef, <2 x i32> <i32 0, i32 1>
// CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> undef, <2 x i32> <i32 2, i32 3>
// CHECK: add <4 x i32> %{{.*}}, %{{.*}}
// CHECK: shufflevector <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> <i32 2, i32 3, i32 0, i32 1>
// CHECK: add <4 x i32> %{{.*}}, %{{.*}}
// CHECK: shufflevector <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> <i32 1, i32 0, i32 3, i32 2>
// CHECK: add <4 x i32> %{{.*}}, %{{.*}}
// CHECK: extractelement <4 x i32> %{{.*}}, i32 0
// CHECK: call i32 @llvm.vector.reduce.add.v16i32(<16 x i32> %{{.*}})
return _mm512_mask_reduce_add_epi32(__M, __W);
}

int test_mm512_mask_reduce_mul_epi32(__mmask16 __M, __m512i __W){
// CHECK-LABEL: @test_mm512_mask_reduce_mul_epi32(
// CHECK: bitcast i16 %{{.*}} to <16 x i1>
// CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}}
// CHECK: bitcast <16 x i32> %{{.*}} to <8 x i64>
// CHECK: shufflevector <8 x i64> %{{.*}}, <8 x i64> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
// CHECK: shufflevector <8 x i64> %{{.*}}, <8 x i64> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
// CHECK: mul <8 x i32> %{{.*}}, %{{.*}}
// CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> undef, <2 x i32> <i32 0, i32 1>
// CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> undef, <2 x i32> <i32 2, i32 3>
// CHECK: mul <4 x i32> %{{.*}}, %{{.*}}
// CHECK: shufflevector <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> <i32 2, i32 3, i32 0, i32 1>
// CHECK: mul <4 x i32> %{{.*}}, %{{.*}}
// CHECK: shufflevector <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> <i32 1, i32 0, i32 3, i32 2>
// CHECK: mul <4 x i32> %{{.*}}, %{{.*}}
// CHECK: extractelement <4 x i32> %{{.*}}, i32 0
// CHECK: call i32 @llvm.vector.reduce.mul.v16i32(<16 x i32> %{{.*}})
return _mm512_mask_reduce_mul_epi32(__M, __W);
}

int test_mm512_mask_reduce_and_epi32(__mmask16 __M, __m512i __W){
// CHECK-LABEL: @test_mm512_mask_reduce_and_epi32(
// CHECK: bitcast i16 %{{.*}} to <16 x i1>
// CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}}
// CHECK: bitcast <16 x i32> %{{.*}} to <8 x i64>
// CHECK: shufflevector <8 x i64> %{{.*}}, <8 x i64> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
// CHECK: shufflevector <8 x i64> %{{.*}}, <8 x i64> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
// CHECK: and <8 x i32> %{{.*}}, %{{.*}}
// CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> undef, <2 x i32> <i32 0, i32 1>
// CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> undef, <2 x i32> <i32 2, i32 3>
// CHECK: and <4 x i32> %{{.*}}, %{{.*}}
// CHECK: shufflevector <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> <i32 2, i32 3, i32 0, i32 1>
// CHECK: and <4 x i32> %{{.*}}, %{{.*}}
// CHECK: shufflevector <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> <i32 1, i32 0, i32 3, i32 2>
// CHECK: and <4 x i32> %{{.*}}, %{{.*}}
// CHECK: extractelement <4 x i32> %{{.*}}, i32 0
// CHECK: call i32 @llvm.vector.reduce.and.v16i32(<16 x i32> %{{.*}})
return _mm512_mask_reduce_and_epi32(__M, __W);
}

int test_mm512_mask_reduce_or_epi32(__mmask16 __M, __m512i __W){
// CHECK-LABEL: @test_mm512_mask_reduce_or_epi32(
// CHECK: bitcast i16 %{{.*}} to <16 x i1>
// CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}}
// CHECK: bitcast <16 x i32> %{{.*}} to <8 x i64>
// CHECK: shufflevector <8 x i64> %{{.*}}, <8 x i64> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
// CHECK: shufflevector <8 x i64> %{{.*}}, <8 x i64> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
// CHECK: or <8 x i32> %{{.*}}, %{{.*}}
// CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> undef, <2 x i32> <i32 0, i32 1>
// CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> undef, <2 x i32> <i32 2, i32 3>
// CHECK: or <4 x i32> %{{.*}}, %{{.*}}
// CHECK: shufflevector <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> <i32 2, i32 3, i32 0, i32 1>
// CHECK: or <4 x i32> %{{.*}}, %{{.*}}
// CHECK: shufflevector <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> <i32 1, i32 0, i32 3, i32 2>
// CHECK: or <4 x i32> %{{.*}}, %{{.*}}
// CHECK: extractelement <4 x i32> %{{.*}}, i32 0
// CHECK: call i32 @llvm.vector.reduce.or.v16i32(<16 x i32> %{{.*}})
return _mm512_mask_reduce_or_epi32(__M, __W);
}

Expand Down
160 changes: 16 additions & 144 deletions clang/test/CodeGen/X86/avx512-reduceMinMaxIntrin.c

Large diffs are not rendered by default.

23 changes: 12 additions & 11 deletions llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -726,7 +726,7 @@ Instruction *InstCombinerImpl::FoldShiftByConstant(Value *Op0, Constant *Op1,
if (BinaryOperator *Op0BO = dyn_cast<BinaryOperator>(Op0)) {
// Turn ((X >> C) + Y) << C -> (X + (Y << C)) & (~0 << C)
Value *V1;
ConstantInt *CC;
const APInt *CC;
switch (Op0BO->getOpcode()) {
default: break;
case Instruction::Add:
Expand All @@ -752,14 +752,14 @@ Instruction *InstCombinerImpl::FoldShiftByConstant(Value *Op0, Constant *Op1,
// Turn (Y + ((X >> C) & CC)) << C -> ((X & (CC << C)) + (Y << C))
Value *Op0BOOp1 = Op0BO->getOperand(1);
if (isLeftShift && Op0BOOp1->hasOneUse() &&
match(Op0BOOp1,
m_And(m_OneUse(m_Shr(m_Value(V1), m_Specific(Op1))),
m_ConstantInt(CC)))) {
Value *YS = // (Y << C)
Builder.CreateShl(Op0BO->getOperand(0), Op1, Op0BO->getName());
match(Op0BOOp1, m_And(m_OneUse(m_Shr(m_Value(V1), m_Specific(Op1))),
m_APInt(CC)))) {
Value *YS = // (Y << C)
Builder.CreateShl(Op0BO->getOperand(0), Op1, Op0BO->getName());
// X & (CC << C)
Value *XM = Builder.CreateAnd(V1, ConstantExpr::getShl(CC, Op1),
V1->getName()+".mask");
Value *XM = Builder.CreateAnd(
V1, ConstantExpr::getShl(ConstantInt::get(Ty, *CC), Op1),
V1->getName() + ".mask");
return BinaryOperator::Create(Op0BO->getOpcode(), YS, XM);
}
LLVM_FALLTHROUGH;
Expand All @@ -785,12 +785,13 @@ Instruction *InstCombinerImpl::FoldShiftByConstant(Value *Op0, Constant *Op1,
if (isLeftShift && Op0BO->getOperand(0)->hasOneUse() &&
match(Op0BO->getOperand(0),
m_And(m_OneUse(m_Shr(m_Value(V1), m_Specific(Op1))),
m_ConstantInt(CC)))) {
m_APInt(CC)))) {
Value *YS = // (Y << C)
Builder.CreateShl(Op0BO->getOperand(1), Op1, Op0BO->getName());
// X & (CC << C)
Value *XM = Builder.CreateAnd(V1, ConstantExpr::getShl(CC, Op1),
V1->getName() + ".mask");
Value *XM = Builder.CreateAnd(
V1, ConstantExpr::getShl(ConstantInt::get(Ty, *CC), Op1),
V1->getName() + ".mask");
return BinaryOperator::Create(Op0BO->getOpcode(), XM, YS);
}

Expand Down
16 changes: 7 additions & 9 deletions llvm/test/Transforms/InstCombine/pr19420.ll
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,10 @@ define i32 @lshr_add_and_shl(i32 %x, i32 %y) {

define <2 x i32> @lshr_add_and_shl_v2i32(<2 x i32> %x, <2 x i32> %y) {
; CHECK-LABEL: @lshr_add_and_shl_v2i32(
; CHECK-NEXT: [[TMP1:%.*]] = lshr <2 x i32> [[X:%.*]], <i32 5, i32 5>
; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i32> [[TMP1]], <i32 127, i32 127>
; CHECK-NEXT: [[TMP3:%.*]] = add <2 x i32> [[TMP2]], [[Y:%.*]]
; CHECK-NEXT: [[TMP4:%.*]] = shl <2 x i32> [[TMP3]], <i32 5, i32 5>
; CHECK-NEXT: ret <2 x i32> [[TMP4]]
; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i32> [[Y:%.*]], <i32 5, i32 5>
; CHECK-NEXT: [[X_MASK:%.*]] = and <2 x i32> [[X:%.*]], <i32 4064, i32 4064>
; CHECK-NEXT: [[TMP2:%.*]] = add <2 x i32> [[X_MASK]], [[TMP1]]
; CHECK-NEXT: ret <2 x i32> [[TMP2]]
;
%1 = lshr <2 x i32> %x, <i32 5, i32 5>
%2 = and <2 x i32> %1, <i32 127, i32 127>
Expand Down Expand Up @@ -160,10 +159,9 @@ define i32 @shl_add_and_lshr(i32 %x, i32 %y) {

define <2 x i32> @shl_add_and_lshr_v2i32(<2 x i32> %x, <2 x i32> %y) {
; CHECK-LABEL: @shl_add_and_lshr_v2i32(
; CHECK-NEXT: [[A:%.*]] = lshr <2 x i32> [[X:%.*]], <i32 4, i32 4>
; CHECK-NEXT: [[B:%.*]] = and <2 x i32> [[A]], <i32 8, i32 8>
; CHECK-NEXT: [[C:%.*]] = add <2 x i32> [[B]], [[Y:%.*]]
; CHECK-NEXT: [[D:%.*]] = shl <2 x i32> [[C]], <i32 4, i32 4>
; CHECK-NEXT: [[C1:%.*]] = shl <2 x i32> [[Y:%.*]], <i32 4, i32 4>
; CHECK-NEXT: [[X_MASK:%.*]] = and <2 x i32> [[X:%.*]], <i32 128, i32 128>
; CHECK-NEXT: [[D:%.*]] = add <2 x i32> [[X_MASK]], [[C1]]
; CHECK-NEXT: ret <2 x i32> [[D]]
;
%a = lshr <2 x i32> %x, <i32 4, i32 4>
Expand Down