[InstCombine] Signed saturation patterns
[llvm-complete.git] / test / Transforms / PhaseOrdering / bitfield-bittests.ll
blob2843a7e761234f442c0b54b424337e80675ad31d
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
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
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.
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.
16 ; Legal i32 is required to allow casting transforms that eliminate the zexts.
17 target datalayout = "n32"
19 define 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]]
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
47 define 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]]
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
75 define 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]]
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
103 define 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]]
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