1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3
4; These patterns are all just traditional clamp pattern.
5; But they are not canonical, the and/or/xor is more canonically represented
6; as an add+icmp.
7
8define i32 @t0_select_cond_and_v0(i32 %X) {
9; CHECK-LABEL: @t0_select_cond_and_v0(
10; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.smax.i32(i32 [[X:%.*]], i32 -32768)
11; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.smin.i32(i32 [[TMP1]], i32 32767)
12; CHECK-NEXT:    ret i32 [[R]]
13;
14  %dont_need_to_clamp_positive = icmp sle i32 %X, 32767
15  %dont_need_to_clamp_negative = icmp sge i32 %X, -32768
16  %clamp_limit = select i1 %dont_need_to_clamp_positive, i32 -32768, i32 32767
17  %dont_need_to_clamp = and i1 %dont_need_to_clamp_positive, %dont_need_to_clamp_negative
18  %R = select i1 %dont_need_to_clamp, i32 %X, i32 %clamp_limit
19  ret i32 %R
20}
21
22define i32 @t0_select_cond_and_v0_logical(i32 %X) {
23; CHECK-LABEL: @t0_select_cond_and_v0_logical(
24; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.smax.i32(i32 [[X:%.*]], i32 -32768)
25; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.smin.i32(i32 [[TMP1]], i32 32767)
26; CHECK-NEXT:    ret i32 [[R]]
27;
28  %dont_need_to_clamp_positive = icmp sle i32 %X, 32767
29  %dont_need_to_clamp_negative = icmp sge i32 %X, -32768
30  %clamp_limit = select i1 %dont_need_to_clamp_positive, i32 -32768, i32 32767
31  %dont_need_to_clamp = select i1 %dont_need_to_clamp_positive, i1 %dont_need_to_clamp_negative, i1 false
32  %R = select i1 %dont_need_to_clamp, i32 %X, i32 %clamp_limit
33  ret i32 %R
34}
35define i32 @t1_select_cond_and_v1(i32 %X) {
36; CHECK-LABEL: @t1_select_cond_and_v1(
37; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.smax.i32(i32 [[X:%.*]], i32 -32768)
38; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.smin.i32(i32 [[TMP1]], i32 32767)
39; CHECK-NEXT:    ret i32 [[R]]
40;
41  %dont_need_to_clamp_positive = icmp sle i32 %X, 32767
42  %dont_need_to_clamp_negative = icmp sge i32 %X, -32768
43  %clamp_limit = select i1 %dont_need_to_clamp_negative, i32 32767, i32 -32768
44  %dont_need_to_clamp = and i1 %dont_need_to_clamp_positive, %dont_need_to_clamp_negative
45  %R = select i1 %dont_need_to_clamp, i32 %X, i32 %clamp_limit
46  ret i32 %R
47}
48
49define i32 @t1_select_cond_and_v1_logical(i32 %X) {
50; CHECK-LABEL: @t1_select_cond_and_v1_logical(
51; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.smax.i32(i32 [[X:%.*]], i32 -32768)
52; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.smin.i32(i32 [[TMP1]], i32 32767)
53; CHECK-NEXT:    ret i32 [[R]]
54;
55  %dont_need_to_clamp_positive = icmp sle i32 %X, 32767
56  %dont_need_to_clamp_negative = icmp sge i32 %X, -32768
57  %clamp_limit = select i1 %dont_need_to_clamp_negative, i32 32767, i32 -32768
58  %dont_need_to_clamp = select i1 %dont_need_to_clamp_positive, i1 %dont_need_to_clamp_negative, i1 false
59  %R = select i1 %dont_need_to_clamp, i32 %X, i32 %clamp_limit
60  ret i32 %R
61}
62
63;-------------------------------------------------------------------------------
64
65define i32 @t2_select_cond_or_v0(i32 %X) {
66; CHECK-LABEL: @t2_select_cond_or_v0(
67; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.smax.i32(i32 [[X:%.*]], i32 -32768)
68; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.smin.i32(i32 [[TMP1]], i32 32767)
69; CHECK-NEXT:    ret i32 [[R]]
70;
71  %need_to_clamp_positive = icmp sgt i32 %X, 32767
72  %need_to_clamp_negative = icmp slt i32 %X, -32768
73  %clamp_limit = select i1 %need_to_clamp_positive, i32 32767, i32 -32768
74  %need_to_clamp = or i1 %need_to_clamp_positive, %need_to_clamp_negative
75  %R = select i1 %need_to_clamp, i32 %clamp_limit, i32 %X
76  ret i32 %R
77}
78
79define i32 @t2_select_cond_or_v0_logical(i32 %X) {
80; CHECK-LABEL: @t2_select_cond_or_v0_logical(
81; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.smax.i32(i32 [[X:%.*]], i32 -32768)
82; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.smin.i32(i32 [[TMP1]], i32 32767)
83; CHECK-NEXT:    ret i32 [[R]]
84;
85  %need_to_clamp_positive = icmp sgt i32 %X, 32767
86  %need_to_clamp_negative = icmp slt i32 %X, -32768
87  %clamp_limit = select i1 %need_to_clamp_positive, i32 32767, i32 -32768
88  %need_to_clamp = select i1 %need_to_clamp_positive, i1 true, i1 %need_to_clamp_negative
89  %R = select i1 %need_to_clamp, i32 %clamp_limit, i32 %X
90  ret i32 %R
91}
92define i32 @t3_select_cond_or_v1(i32 %X) {
93; CHECK-LABEL: @t3_select_cond_or_v1(
94; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.smax.i32(i32 [[X:%.*]], i32 -32768)
95; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.smin.i32(i32 [[TMP1]], i32 32767)
96; CHECK-NEXT:    ret i32 [[R]]
97;
98  %need_to_clamp_positive = icmp sgt i32 %X, 32767
99  %need_to_clamp_negative = icmp slt i32 %X, -32768
100  %clamp_limit = select i1 %need_to_clamp_negative, i32 -32768, i32 32767
101  %need_to_clamp = or i1 %need_to_clamp_positive, %need_to_clamp_negative
102  %R = select i1 %need_to_clamp, i32 %clamp_limit, i32 %X
103  ret i32 %R
104}
105
106define i32 @t3_select_cond_or_v1_logical(i32 %X) {
107; CHECK-LABEL: @t3_select_cond_or_v1_logical(
108; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.smax.i32(i32 [[X:%.*]], i32 -32768)
109; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.smin.i32(i32 [[TMP1]], i32 32767)
110; CHECK-NEXT:    ret i32 [[R]]
111;
112  %need_to_clamp_positive = icmp sgt i32 %X, 32767
113  %need_to_clamp_negative = icmp slt i32 %X, -32768
114  %clamp_limit = select i1 %need_to_clamp_negative, i32 -32768, i32 32767
115  %need_to_clamp = select i1 %need_to_clamp_positive, i1 true, i1 %need_to_clamp_negative
116  %R = select i1 %need_to_clamp, i32 %clamp_limit, i32 %X
117  ret i32 %R
118}
119
120;-------------------------------------------------------------------------------
121
122define i32 @t4_select_cond_xor_v0(i32 %X) {
123; CHECK-LABEL: @t4_select_cond_xor_v0(
124; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.smax.i32(i32 [[X:%.*]], i32 -32768)
125; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.smin.i32(i32 [[TMP1]], i32 32767)
126; CHECK-NEXT:    ret i32 [[R]]
127;
128  %need_to_clamp_positive = icmp sgt i32 %X, 32767
129  %dont_need_to_clamp_negative = icmp sgt i32 %X, -32768
130  %clamp_limit = select i1 %need_to_clamp_positive, i32 32767, i32 -32768
131  %dont_need_to_clamp = xor i1 %need_to_clamp_positive, %dont_need_to_clamp_negative
132  %R = select i1 %dont_need_to_clamp, i32 %X, i32 %clamp_limit
133  ret i32 %R
134}
135define i32 @t4_select_cond_xor_v1(i32 %X) {
136; CHECK-LABEL: @t4_select_cond_xor_v1(
137; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.smax.i32(i32 [[X:%.*]], i32 -32768)
138; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.smin.i32(i32 [[TMP1]], i32 32767)
139; CHECK-NEXT:    ret i32 [[R]]
140;
141  %need_to_clamp_positive = icmp sgt i32 %X, 32767
142  %dont_need_to_clamp_negative = icmp sgt i32 %X, -32768
143  %clamp_limit = select i1 %dont_need_to_clamp_negative, i32 32767, i32 -32768
144  %dont_need_to_clamp = xor i1 %need_to_clamp_positive, %dont_need_to_clamp_negative
145  %R = select i1 %dont_need_to_clamp, i32 %X, i32 %clamp_limit
146  ret i32 %R
147}
148
149define i32 @t5_select_cond_xor_v2(i32 %X) {
150; CHECK-LABEL: @t5_select_cond_xor_v2(
151; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.smax.i32(i32 [[X:%.*]], i32 -32768)
152; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.smin.i32(i32 [[TMP1]], i32 32767)
153; CHECK-NEXT:    ret i32 [[R]]
154;
155  %dont_need_to_clamp_positive = icmp sle i32 %X, 32767
156  %need_to_clamp_negative = icmp sle i32 %X, -32768
157  %clamp_limit = select i1 %need_to_clamp_negative, i32 -32768, i32 32767
158  %dont_need_to_clamp = xor i1 %dont_need_to_clamp_positive, %need_to_clamp_negative
159  %R = select i1 %dont_need_to_clamp, i32 %X, i32 %clamp_limit
160  ret i32 %R
161}
162define i32 @t5_select_cond_xor_v3(i32 %X) {
163; CHECK-LABEL: @t5_select_cond_xor_v3(
164; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.smax.i32(i32 [[X:%.*]], i32 -32768)
165; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.smin.i32(i32 [[TMP1]], i32 32767)
166; CHECK-NEXT:    ret i32 [[R]]
167;
168  %dont_need_to_clamp_positive = icmp sle i32 %X, 32767
169  %need_to_clamp_negative = icmp sle i32 %X, -32768
170  %clamp_limit = select i1 %dont_need_to_clamp_positive, i32 -32768, i32 32767
171  %dont_need_to_clamp = xor i1 %dont_need_to_clamp_positive, %need_to_clamp_negative
172  %R = select i1 %dont_need_to_clamp, i32 %X, i32 %clamp_limit
173  ret i32 %R
174}
175