xref: /llvm-project/llvm/test/Transforms/InstCombine/reduction-or-sext-zext-i1.ll (revision 2caaec65c04ea7d0e9568b7895b7a46d6100cb75)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3
4target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
5
6define i1 @reduce_or_self(<8 x i1> %x) {
7; CHECK-LABEL: @reduce_or_self(
8; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <8 x i1> [[X:%.*]] to i8
9; CHECK-NEXT:    [[RES:%.*]] = icmp ne i8 [[TMP1]], 0
10; CHECK-NEXT:    ret i1 [[RES]]
11;
12  %res = call i1 @llvm.vector.reduce.or.v8i32(<8 x i1> %x)
13  ret i1 %res
14}
15
16define i32 @reduce_or_sext(<4 x i1> %x) {
17; CHECK-LABEL: @reduce_or_sext(
18; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <4 x i1> [[X:%.*]] to i4
19; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i4 [[TMP1]], 0
20; CHECK-NEXT:    [[RES:%.*]] = sext i1 [[TMP2]] 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.or.v4i32(<4 x i32> %sext)
25  ret i32 %res
26}
27
28define i64 @reduce_or_zext(<8 x i1> %x) {
29; CHECK-LABEL: @reduce_or_zext(
30; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <8 x i1> [[X:%.*]] to i8
31; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i8 [[TMP1]], 0
32; CHECK-NEXT:    [[RES:%.*]] = zext i1 [[TMP2]] to i64
33; CHECK-NEXT:    ret i64 [[RES]]
34;
35  %zext = zext <8 x i1> %x to <8 x i64>
36  %res = call i64 @llvm.vector.reduce.or.v8i64(<8 x i64> %zext)
37  ret i64 %res
38}
39
40define i16 @reduce_or_sext_same(<16 x i1> %x) {
41; CHECK-LABEL: @reduce_or_sext_same(
42; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <16 x i1> [[X:%.*]] to i16
43; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i16 [[TMP1]], 0
44; CHECK-NEXT:    [[RES:%.*]] = sext i1 [[TMP2]] to i16
45; CHECK-NEXT:    ret i16 [[RES]]
46;
47  %sext = sext <16 x i1> %x to <16 x i16>
48  %res = call i16 @llvm.vector.reduce.or.v16i16(<16 x i16> %sext)
49  ret i16 %res
50}
51
52define i8 @reduce_or_zext_long(<128 x i1> %x) {
53; CHECK-LABEL: @reduce_or_zext_long(
54; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <128 x i1> [[X:%.*]] to i128
55; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i128 [[TMP1]], 0
56; CHECK-NEXT:    [[RES:%.*]] = sext i1 [[TMP2]] to i8
57; CHECK-NEXT:    ret i8 [[RES]]
58;
59  %sext = sext <128 x i1> %x to <128 x i8>
60  %res = call i8 @llvm.vector.reduce.or.v128i8(<128 x i8> %sext)
61  ret i8 %res
62}
63
64@glob = external global i8, align 1
65define i8 @reduce_or_zext_long_external_use(<128 x i1> %x) {
66; CHECK-LABEL: @reduce_or_zext_long_external_use(
67; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <128 x i1> [[X:%.*]] to i128
68; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i128 [[TMP1]], 0
69; CHECK-NEXT:    [[RES:%.*]] = sext i1 [[TMP2]] to i8
70; CHECK-NEXT:    [[TMP3:%.*]] = extractelement <128 x i1> [[X]], i64 0
71; CHECK-NEXT:    [[EXT:%.*]] = sext i1 [[TMP3]] to i8
72; CHECK-NEXT:    store i8 [[EXT]], ptr @glob, align 1
73; CHECK-NEXT:    ret i8 [[RES]]
74;
75  %sext = sext <128 x i1> %x to <128 x i8>
76  %res = call i8 @llvm.vector.reduce.or.v128i8(<128 x i8> %sext)
77  %ext = extractelement <128 x i8> %sext, i32 0
78  store i8 %ext, ptr @glob, align 1
79  ret i8 %res
80}
81
82@glob1 = external global i64, align 8
83define i64 @reduce_or_zext_external_use(<8 x i1> %x) {
84; CHECK-LABEL: @reduce_or_zext_external_use(
85; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <8 x i1> [[X:%.*]] to i8
86; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i8 [[TMP1]], 0
87; CHECK-NEXT:    [[RES:%.*]] = zext i1 [[TMP2]] to i64
88; CHECK-NEXT:    [[TMP3:%.*]] = extractelement <8 x i1> [[X]], i64 0
89; CHECK-NEXT:    [[EXT:%.*]] = zext i1 [[TMP3]] to i64
90; CHECK-NEXT:    store i64 [[EXT]], ptr @glob1, align 8
91; CHECK-NEXT:    ret i64 [[RES]]
92;
93  %zext = zext <8 x i1> %x to <8 x i64>
94  %res = call i64 @llvm.vector.reduce.or.v8i64(<8 x i64> %zext)
95  %ext = extractelement <8 x i64> %zext, i32 0
96  store i64 %ext, ptr @glob1, align 8
97  ret i64 %res
98}
99
100define i1 @reduce_or_pointer_cast(ptr %arg, ptr %arg1) {
101; CHECK-LABEL: @reduce_or_pointer_cast(
102; CHECK-NEXT:  bb:
103; CHECK-NEXT:    [[LHS1:%.*]] = load i64, ptr [[ARG1:%.*]], align 8
104; CHECK-NEXT:    [[RHS2:%.*]] = load i64, ptr [[ARG:%.*]], align 8
105; CHECK-NEXT:    [[ANY_NE_NOT:%.*]] = icmp eq i64 [[LHS1]], [[RHS2]]
106; CHECK-NEXT:    ret i1 [[ANY_NE_NOT]]
107;
108bb:
109  %lhs = load <8 x i8>, ptr %arg1
110  %rhs = load <8 x i8>, ptr %arg
111  %cmp = icmp ne <8 x i8> %lhs, %rhs
112  %any_ne = call i1 @llvm.vector.reduce.or.v8i32(<8 x i1> %cmp)
113  %all_eq = xor i1 %any_ne, 1
114  ret i1 %all_eq
115}
116
117define i1 @reduce_or_pointer_cast_wide(ptr %arg, ptr %arg1) {
118; CHECK-LABEL: @reduce_or_pointer_cast_wide(
119; CHECK-NEXT:  bb:
120; CHECK-NEXT:    [[LHS:%.*]] = load <8 x i16>, ptr [[ARG1:%.*]], align 16
121; CHECK-NEXT:    [[RHS:%.*]] = load <8 x i16>, ptr [[ARG:%.*]], align 16
122; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <8 x i16> [[LHS]], [[RHS]]
123; CHECK-NEXT:    [[TMP0:%.*]] = bitcast <8 x i1> [[CMP]] to i8
124; CHECK-NEXT:    [[ANY_NE_NOT:%.*]] = icmp eq i8 [[TMP0]], 0
125; CHECK-NEXT:    ret i1 [[ANY_NE_NOT]]
126;
127bb:
128  %lhs = load <8 x i16>, ptr %arg1
129  %rhs = load <8 x i16>, ptr %arg
130  %cmp = icmp ne <8 x i16> %lhs, %rhs
131  %any_ne = call i1 @llvm.vector.reduce.or.v8i32(<8 x i1> %cmp)
132  %all_eq = xor i1 %any_ne, 1
133  ret i1 %all_eq
134}
135
136
137define i1 @reduce_or_pointer_cast_ne(ptr %arg, ptr %arg1) {
138; CHECK-LABEL: @reduce_or_pointer_cast_ne(
139; CHECK-NEXT:  bb:
140; CHECK-NEXT:    [[LHS1:%.*]] = load i64, ptr [[ARG1:%.*]], align 8
141; CHECK-NEXT:    [[RHS2:%.*]] = load i64, ptr [[ARG:%.*]], align 8
142; CHECK-NEXT:    [[ANY_NE:%.*]] = icmp ne i64 [[LHS1]], [[RHS2]]
143; CHECK-NEXT:    ret i1 [[ANY_NE]]
144;
145bb:
146  %lhs = load <8 x i8>, ptr %arg1
147  %rhs = load <8 x i8>, ptr %arg
148  %cmp = icmp ne <8 x i8> %lhs, %rhs
149  %any_ne = call i1 @llvm.vector.reduce.or.v8i32(<8 x i1> %cmp)
150  ret i1 %any_ne
151}
152
153define i1 @reduce_or_pointer_cast_ne_wide(ptr %arg, ptr %arg1) {
154; CHECK-LABEL: @reduce_or_pointer_cast_ne_wide(
155; CHECK-NEXT:  bb:
156; CHECK-NEXT:    [[LHS:%.*]] = load <8 x i16>, ptr [[ARG1:%.*]], align 16
157; CHECK-NEXT:    [[RHS:%.*]] = load <8 x i16>, ptr [[ARG:%.*]], align 16
158; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <8 x i16> [[LHS]], [[RHS]]
159; CHECK-NEXT:    [[TMP0:%.*]] = bitcast <8 x i1> [[CMP]] to i8
160; CHECK-NEXT:    [[ANY_NE:%.*]] = icmp ne i8 [[TMP0]], 0
161; CHECK-NEXT:    ret i1 [[ANY_NE]]
162;
163bb:
164  %lhs = load <8 x i16>, ptr %arg1
165  %rhs = load <8 x i16>, ptr %arg
166  %cmp = icmp ne <8 x i16> %lhs, %rhs
167  %any_ne = call i1 @llvm.vector.reduce.or.v8i32(<8 x i1> %cmp)
168  ret i1 %any_ne
169}
170
171declare i1 @llvm.vector.reduce.or.v8i32(<8 x i1> %a)
172declare i32 @llvm.vector.reduce.or.v4i32(<4 x i32> %a)
173declare i64 @llvm.vector.reduce.or.v8i64(<8 x i64> %a)
174declare i16 @llvm.vector.reduce.or.v16i16(<16 x i16> %a)
175declare i8 @llvm.vector.reduce.or.v128i8(<128 x i8> %a)
176