xref: /llvm-project/llvm/test/Transforms/InstCombine/reduction-xor-sext-zext-i1.ll (revision b8f3024a315074e0f880542c33cb89681eebc5a3)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3
4define i1 @reduce_xor_self(<8 x i1> %x) {
5; CHECK-LABEL: @reduce_xor_self(
6; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <8 x i1> [[X:%.*]] to i8
7; CHECK-NEXT:    [[TMP2:%.*]] = call range(i8 0, 9) i8 @llvm.ctpop.i8(i8 [[TMP1]])
8; CHECK-NEXT:    [[RES:%.*]] = trunc i8 [[TMP2]] to i1
9; CHECK-NEXT:    ret i1 [[RES]]
10;
11  %res = call i1 @llvm.vector.reduce.xor.v8i32(<8 x i1> %x)
12  ret i1 %res
13}
14
15define i32 @reduce_xor_sext(<4 x i1> %x) {
16; CHECK-LABEL: @reduce_xor_sext(
17; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <4 x i1> [[X:%.*]] to i4
18; CHECK-NEXT:    [[TMP2:%.*]] = call range(i4 0, 5) i4 @llvm.ctpop.i4(i4 [[TMP1]])
19; CHECK-NEXT:    [[TMP3:%.*]] = trunc i4 [[TMP2]] to i1
20; CHECK-NEXT:    [[RES:%.*]] = sext i1 [[TMP3]] to i32
21; CHECK-NEXT:    ret i32 [[RES]]
22;
23  %sext = sext <4 x i1> %x to <4 x i32>
24  %res = call i32 @llvm.vector.reduce.xor.v4i32(<4 x i32> %sext)
25  ret i32 %res
26}
27
28define i64 @reduce_xor_zext(<8 x i1> %x) {
29; CHECK-LABEL: @reduce_xor_zext(
30; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <8 x i1> [[X:%.*]] to i8
31; CHECK-NEXT:    [[TMP2:%.*]] = call range(i8 0, 9) i8 @llvm.ctpop.i8(i8 [[TMP1]])
32; CHECK-NEXT:    [[TMP3:%.*]] = and i8 [[TMP2]], 1
33; CHECK-NEXT:    [[RES:%.*]] = zext nneg i8 [[TMP3]] to i64
34; CHECK-NEXT:    ret i64 [[RES]]
35;
36  %zext = zext <8 x i1> %x to <8 x i64>
37  %res = call i64 @llvm.vector.reduce.xor.v8i64(<8 x i64> %zext)
38  ret i64 %res
39}
40
41define i16 @reduce_xor_sext_same(<16 x i1> %x) {
42; CHECK-LABEL: @reduce_xor_sext_same(
43; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <16 x i1> [[X:%.*]] to i16
44; CHECK-NEXT:    [[TMP2:%.*]] = call range(i16 0, 17) i16 @llvm.ctpop.i16(i16 [[TMP1]])
45; CHECK-NEXT:    [[TMP3:%.*]] = and i16 [[TMP2]], 1
46; CHECK-NEXT:    [[SEXT:%.*]] = sub nsw i16 0, [[TMP3]]
47; CHECK-NEXT:    ret i16 [[SEXT]]
48;
49  %sext = sext <16 x i1> %x to <16 x i16>
50  %res = call i16 @llvm.vector.reduce.xor.v16i16(<16 x i16> %sext)
51  ret i16 %res
52}
53
54define i8 @reduce_xor_zext_long(<128 x i1> %x) {
55; CHECK-LABEL: @reduce_xor_zext_long(
56; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <128 x i1> [[X:%.*]] to i128
57; CHECK-NEXT:    [[TMP2:%.*]] = call range(i128 0, 129) i128 @llvm.ctpop.i128(i128 [[TMP1]])
58; CHECK-NEXT:    [[TMP3:%.*]] = trunc i128 [[TMP2]] to i1
59; CHECK-NEXT:    [[RES:%.*]] = sext i1 [[TMP3]] to i8
60; CHECK-NEXT:    ret i8 [[RES]]
61;
62  %sext = sext <128 x i1> %x to <128 x i8>
63  %res = call i8 @llvm.vector.reduce.xor.v128i8(<128 x i8> %sext)
64  ret i8 %res
65}
66
67@glob = external global i8, align 1
68define i8 @reduce_xor_zext_long_external_use(<128 x i1> %x) {
69; CHECK-LABEL: @reduce_xor_zext_long_external_use(
70; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <128 x i1> [[X:%.*]] to i128
71; CHECK-NEXT:    [[TMP2:%.*]] = call range(i128 0, 129) i128 @llvm.ctpop.i128(i128 [[TMP1]])
72; CHECK-NEXT:    [[TMP3:%.*]] = trunc i128 [[TMP2]] to i1
73; CHECK-NEXT:    [[RES:%.*]] = sext i1 [[TMP3]] to i8
74; CHECK-NEXT:    [[TMP5:%.*]] = extractelement <128 x i1> [[X]], i64 0
75; CHECK-NEXT:    [[EXT:%.*]] = sext i1 [[TMP5]] to i8
76; CHECK-NEXT:    store i8 [[EXT]], ptr @glob, align 1
77; CHECK-NEXT:    ret i8 [[RES]]
78;
79  %sext = sext <128 x i1> %x to <128 x i8>
80  %res = call i8 @llvm.vector.reduce.xor.v128i8(<128 x i8> %sext)
81  %ext = extractelement <128 x i8> %sext, i32 0
82  store i8 %ext, ptr @glob, align 1
83  ret i8 %res
84}
85
86@glob1 = external global i64, align 8
87define i64 @reduce_xor_zext_external_use(<8 x i1> %x) {
88; CHECK-LABEL: @reduce_xor_zext_external_use(
89; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <8 x i1> [[X:%.*]] to i8
90; CHECK-NEXT:    [[TMP2:%.*]] = call range(i8 0, 9) i8 @llvm.ctpop.i8(i8 [[TMP1]])
91; CHECK-NEXT:    [[TMP3:%.*]] = and i8 [[TMP2]], 1
92; CHECK-NEXT:    [[RES:%.*]] = zext nneg i8 [[TMP3]] to i64
93; CHECK-NEXT:    [[TMP4:%.*]] = extractelement <8 x i1> [[X]], i64 0
94; CHECK-NEXT:    [[EXT:%.*]] = zext i1 [[TMP4]] to i64
95; CHECK-NEXT:    store i64 [[EXT]], ptr @glob1, align 8
96; CHECK-NEXT:    ret i64 [[RES]]
97;
98  %zext = zext <8 x i1> %x to <8 x i64>
99  %res = call i64 @llvm.vector.reduce.xor.v8i64(<8 x i64> %zext)
100  %ext = extractelement <8 x i64> %zext, i32 0
101  store i64 %ext, ptr @glob1, align 8
102  ret i64 %res
103}
104
105declare i1 @llvm.vector.reduce.xor.v8i32(<8 x i1> %a)
106declare i32 @llvm.vector.reduce.xor.v4i32(<4 x i32> %a)
107declare i64 @llvm.vector.reduce.xor.v8i64(<8 x i64> %a)
108declare i16 @llvm.vector.reduce.xor.v16i16(<16 x i16> %a)
109declare i8 @llvm.vector.reduce.xor.v128i8(<128 x i8> %a)
110