1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -O3 -S < %s                    | FileCheck %s
3; RUN: opt -passes='default<O3>' -S < %s  | FileCheck %s
4
5; These are tests that check for set/clear bits in a bitfield based on PR37098:
6; https://bugs.llvm.org/show_bug.cgi?id=37098
7;
8; The initial IR from clang has been transformed by SROA, but no other passes
9; have run yet. In all cases, we should reduce these to a mask and compare
10; instead of shift/cast/logic ops.
11;
12; Currently, this happens mostly through a combination of instcombine and
13; aggressive-instcombine. If pass ordering changes, we may have to adjust
14; the pattern matching in 1 or both of those passes.
15
16; Legal i32 is required to allow casting transforms that eliminate the zexts.
17target datalayout = "n32"
18
19define i32 @allclear(i32 %a) {
20; CHECK-LABEL: @allclear(
21; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[A:%.*]], 15
22; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0
23; CHECK-NEXT:    [[TMP3:%.*]] = zext i1 [[TMP2]] to i32
24; CHECK-NEXT:    ret i32 [[TMP3]]
25;
26  %a.sroa.0.0.trunc = trunc i32 %a to i8
27  %a.sroa.5.0.shift = lshr i32 %a, 8
28  %bf.clear = and i8 %a.sroa.0.0.trunc, 1
29  %bf.cast = zext i8 %bf.clear to i32
30  %bf.lshr = lshr i8 %a.sroa.0.0.trunc, 1
31  %bf.clear2 = and i8 %bf.lshr, 1
32  %bf.cast3 = zext i8 %bf.clear2 to i32
33  %or = or i32 %bf.cast, %bf.cast3
34  %bf.lshr5 = lshr i8 %a.sroa.0.0.trunc, 2
35  %bf.clear6 = and i8 %bf.lshr5, 1
36  %bf.cast7 = zext i8 %bf.clear6 to i32
37  %or8 = or i32 %or, %bf.cast7
38  %bf.lshr10 = lshr i8 %a.sroa.0.0.trunc, 3
39  %bf.clear11 = and i8 %bf.lshr10, 1
40  %bf.cast12 = zext i8 %bf.clear11 to i32
41  %or13 = or i32 %or8, %bf.cast12
42  %cmp = icmp eq i32 %or13, 0
43  %conv = zext i1 %cmp to i32
44  ret i32 %conv
45}
46
47define i32 @anyset(i32 %a) {
48; CHECK-LABEL: @anyset(
49; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[A:%.*]], 15
50; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0
51; CHECK-NEXT:    [[TMP3:%.*]] = zext i1 [[TMP2]] to i32
52; CHECK-NEXT:    ret i32 [[TMP3]]
53;
54  %a.sroa.0.0.trunc = trunc i32 %a to i8
55  %a.sroa.5.0.shift = lshr i32 %a, 8
56  %bf.clear = and i8 %a.sroa.0.0.trunc, 1
57  %bf.cast = zext i8 %bf.clear to i32
58  %bf.lshr = lshr i8 %a.sroa.0.0.trunc, 1
59  %bf.clear2 = and i8 %bf.lshr, 1
60  %bf.cast3 = zext i8 %bf.clear2 to i32
61  %or = or i32 %bf.cast, %bf.cast3
62  %bf.lshr5 = lshr i8 %a.sroa.0.0.trunc, 2
63  %bf.clear6 = and i8 %bf.lshr5, 1
64  %bf.cast7 = zext i8 %bf.clear6 to i32
65  %or8 = or i32 %or, %bf.cast7
66  %bf.lshr10 = lshr i8 %a.sroa.0.0.trunc, 3
67  %bf.clear11 = and i8 %bf.lshr10, 1
68  %bf.cast12 = zext i8 %bf.clear11 to i32
69  %or13 = or i32 %or8, %bf.cast12
70  %cmp = icmp ne i32 %or13, 0
71  %conv = zext i1 %cmp to i32
72  ret i32 %conv
73}
74
75define i32 @allset(i32 %a) {
76; CHECK-LABEL: @allset(
77; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[A:%.*]], 15
78; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 15
79; CHECK-NEXT:    [[TMP3:%.*]] = zext i1 [[TMP2]] to i32
80; CHECK-NEXT:    ret i32 [[TMP3]]
81;
82  %a.sroa.0.0.trunc = trunc i32 %a to i8
83  %a.sroa.5.0.shift = lshr i32 %a, 8
84  %bf.clear = and i8 %a.sroa.0.0.trunc, 1
85  %bf.cast = zext i8 %bf.clear to i32
86  %bf.lshr = lshr i8 %a.sroa.0.0.trunc, 1
87  %bf.clear2 = and i8 %bf.lshr, 1
88  %bf.cast3 = zext i8 %bf.clear2 to i32
89  %and = and i32 %bf.cast, %bf.cast3
90  %bf.lshr5 = lshr i8 %a.sroa.0.0.trunc, 2
91  %bf.clear6 = and i8 %bf.lshr5, 1
92  %bf.cast7 = zext i8 %bf.clear6 to i32
93  %and8 = and i32 %and, %bf.cast7
94  %bf.lshr10 = lshr i8 %a.sroa.0.0.trunc, 3
95  %bf.clear11 = and i8 %bf.lshr10, 1
96  %bf.cast12 = zext i8 %bf.clear11 to i32
97  %and13 = and i32 %and8, %bf.cast12
98  %cmp = icmp ne i32 %and13, 0
99  %conv = zext i1 %cmp to i32
100  ret i32 %conv
101}
102
103define i32 @anyclear(i32 %a) {
104; CHECK-LABEL: @anyclear(
105; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[A:%.*]], 15
106; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 15
107; CHECK-NEXT:    [[TMP3:%.*]] = zext i1 [[TMP2]] to i32
108; CHECK-NEXT:    ret i32 [[TMP3]]
109;
110  %a.sroa.0.0.trunc = trunc i32 %a to i8
111  %a.sroa.5.0.shift = lshr i32 %a, 8
112  %bf.clear = and i8 %a.sroa.0.0.trunc, 1
113  %bf.cast = zext i8 %bf.clear to i32
114  %bf.lshr = lshr i8 %a.sroa.0.0.trunc, 1
115  %bf.clear2 = and i8 %bf.lshr, 1
116  %bf.cast3 = zext i8 %bf.clear2 to i32
117  %and = and i32 %bf.cast, %bf.cast3
118  %bf.lshr5 = lshr i8 %a.sroa.0.0.trunc, 2
119  %bf.clear6 = and i8 %bf.lshr5, 1
120  %bf.cast7 = zext i8 %bf.clear6 to i32
121  %and8 = and i32 %and, %bf.cast7
122  %bf.lshr10 = lshr i8 %a.sroa.0.0.trunc, 3
123  %bf.clear11 = and i8 %bf.lshr10, 1
124  %bf.cast12 = zext i8 %bf.clear11 to i32
125  %and13 = and i32 %and8, %bf.cast12
126  %cmp = icmp eq i32 %and13, 0
127  %conv = zext i1 %cmp to i32
128  ret i32 %conv
129}
130
131