1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
4 ; These patterns are all just traditional clamp pattern.
5 ; But they are not canonical, the and/or/xor is more canonically represented
8 define 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]]
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
22 define 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]]
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
35 define 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]]
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
49 define 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]]
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
63 ;-------------------------------------------------------------------------------
65 define 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]]
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
79 define 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]]
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
92 define 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]]
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
106 define 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]]
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
120 ;-------------------------------------------------------------------------------
122 define 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]]
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
135 define 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]]
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
149 define 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]]
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
162 define 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]]
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