1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -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:%.*]] = icmp sgt i32 [[X:%.*]], -32768
11; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[X]], i32 -32768
12; CHECK-NEXT:    [[TMP3:%.*]] = icmp slt i32 [[TMP2]], 32767
13; CHECK-NEXT:    [[R:%.*]] = select i1 [[TMP3]], i32 [[TMP2]], i32 32767
14; CHECK-NEXT:    ret i32 [[R]]
15;
16  %dont_need_to_clamp_positive = icmp sle i32 %X, 32767
17  %dont_need_to_clamp_negative = icmp sge i32 %X, -32768
18  %clamp_limit = select i1 %dont_need_to_clamp_positive, i32 -32768, i32 32767
19  %dont_need_to_clamp = and i1 %dont_need_to_clamp_positive, %dont_need_to_clamp_negative
20  %R = select i1 %dont_need_to_clamp, i32 %X, i32 %clamp_limit
21  ret i32 %R
22}
23define i32 @t1_select_cond_and_v1(i32 %X) {
24; CHECK-LABEL: @t1_select_cond_and_v1(
25; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 [[X:%.*]], -32768
26; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[X]], i32 -32768
27; CHECK-NEXT:    [[TMP3:%.*]] = icmp slt i32 [[TMP2]], 32767
28; CHECK-NEXT:    [[R:%.*]] = select i1 [[TMP3]], i32 [[TMP2]], i32 32767
29; CHECK-NEXT:    ret i32 [[R]]
30;
31  %dont_need_to_clamp_positive = icmp sle i32 %X, 32767
32  %dont_need_to_clamp_negative = icmp sge i32 %X, -32768
33  %clamp_limit = select i1 %dont_need_to_clamp_negative, i32 32767, i32 -32768
34  %dont_need_to_clamp = and i1 %dont_need_to_clamp_positive, %dont_need_to_clamp_negative
35  %R = select i1 %dont_need_to_clamp, i32 %X, i32 %clamp_limit
36  ret i32 %R
37}
38
39;-------------------------------------------------------------------------------
40
41define i32 @t2_select_cond_or_v0(i32 %X) {
42; CHECK-LABEL: @t2_select_cond_or_v0(
43; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 [[X:%.*]], -32768
44; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[X]], i32 -32768
45; CHECK-NEXT:    [[TMP3:%.*]] = icmp slt i32 [[TMP2]], 32767
46; CHECK-NEXT:    [[R:%.*]] = select i1 [[TMP3]], i32 [[TMP2]], i32 32767
47; CHECK-NEXT:    ret i32 [[R]]
48;
49  %need_to_clamp_positive = icmp sgt i32 %X, 32767
50  %need_to_clamp_negative = icmp slt i32 %X, -32768
51  %clamp_limit = select i1 %need_to_clamp_positive, i32 32767, i32 -32768
52  %need_to_clamp = or i1 %need_to_clamp_positive, %need_to_clamp_negative
53  %R = select i1 %need_to_clamp, i32 %clamp_limit, i32 %X
54  ret i32 %R
55}
56define i32 @t3_select_cond_or_v1(i32 %X) {
57; CHECK-LABEL: @t3_select_cond_or_v1(
58; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 [[X:%.*]], -32768
59; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[X]], i32 -32768
60; CHECK-NEXT:    [[TMP3:%.*]] = icmp slt i32 [[TMP2]], 32767
61; CHECK-NEXT:    [[R:%.*]] = select i1 [[TMP3]], i32 [[TMP2]], i32 32767
62; CHECK-NEXT:    ret i32 [[R]]
63;
64  %need_to_clamp_positive = icmp sgt i32 %X, 32767
65  %need_to_clamp_negative = icmp slt i32 %X, -32768
66  %clamp_limit = select i1 %need_to_clamp_negative, i32 -32768, i32 32767
67  %need_to_clamp = or i1 %need_to_clamp_positive, %need_to_clamp_negative
68  %R = select i1 %need_to_clamp, i32 %clamp_limit, i32 %X
69  ret i32 %R
70}
71
72;-------------------------------------------------------------------------------
73
74define i32 @t4_select_cond_xor_v0(i32 %X) {
75; CHECK-LABEL: @t4_select_cond_xor_v0(
76; CHECK-NEXT:    [[DOTINV1:%.*]] = icmp sgt i32 [[X:%.*]], -32768
77; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[DOTINV1]], i32 [[X]], i32 -32768
78; CHECK-NEXT:    [[TMP2:%.*]] = icmp slt i32 [[TMP1]], 32767
79; CHECK-NEXT:    [[R:%.*]] = select i1 [[TMP2]], i32 [[TMP1]], i32 32767
80; CHECK-NEXT:    ret i32 [[R]]
81;
82  %need_to_clamp_positive = icmp sgt i32 %X, 32767
83  %dont_need_to_clamp_negative = icmp sgt i32 %X, -32768
84  %clamp_limit = select i1 %need_to_clamp_positive, i32 32767, i32 -32768
85  %dont_need_to_clamp = xor i1 %need_to_clamp_positive, %dont_need_to_clamp_negative
86  %R = select i1 %dont_need_to_clamp, i32 %X, i32 %clamp_limit
87  ret i32 %R
88}
89define i32 @t4_select_cond_xor_v1(i32 %X) {
90; CHECK-LABEL: @t4_select_cond_xor_v1(
91; CHECK-NEXT:    [[DOTINV1:%.*]] = icmp sgt i32 [[X:%.*]], -32768
92; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[DOTINV1]], i32 [[X]], i32 -32768
93; CHECK-NEXT:    [[TMP2:%.*]] = icmp slt i32 [[TMP1]], 32767
94; CHECK-NEXT:    [[R:%.*]] = select i1 [[TMP2]], i32 [[TMP1]], i32 32767
95; CHECK-NEXT:    ret i32 [[R]]
96;
97  %need_to_clamp_positive = icmp sgt i32 %X, 32767
98  %dont_need_to_clamp_negative = icmp sgt i32 %X, -32768
99  %clamp_limit = select i1 %dont_need_to_clamp_negative, i32 32767, i32 -32768
100  %dont_need_to_clamp = xor i1 %need_to_clamp_positive, %dont_need_to_clamp_negative
101  %R = select i1 %dont_need_to_clamp, i32 %X, i32 %clamp_limit
102  ret i32 %R
103}
104
105define i32 @t5_select_cond_xor_v2(i32 %X) {
106; CHECK-LABEL: @t5_select_cond_xor_v2(
107; CHECK-NEXT:    [[DOTINV1:%.*]] = icmp sgt i32 [[X:%.*]], -32768
108; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[DOTINV1]], i32 [[X]], i32 -32768
109; CHECK-NEXT:    [[TMP2:%.*]] = icmp slt i32 [[TMP1]], 32767
110; CHECK-NEXT:    [[R:%.*]] = select i1 [[TMP2]], i32 [[TMP1]], i32 32767
111; CHECK-NEXT:    ret i32 [[R]]
112;
113  %dont_need_to_clamp_positive = icmp sle i32 %X, 32767
114  %need_to_clamp_negative = icmp sle i32 %X, -32768
115  %clamp_limit = select i1 %need_to_clamp_negative, i32 -32768, i32 32767
116  %dont_need_to_clamp = xor i1 %dont_need_to_clamp_positive, %need_to_clamp_negative
117  %R = select i1 %dont_need_to_clamp, i32 %X, i32 %clamp_limit
118  ret i32 %R
119}
120define i32 @t5_select_cond_xor_v3(i32 %X) {
121; CHECK-LABEL: @t5_select_cond_xor_v3(
122; CHECK-NEXT:    [[DOTINV1:%.*]] = icmp sgt i32 [[X:%.*]], -32768
123; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[DOTINV1]], i32 [[X]], i32 -32768
124; CHECK-NEXT:    [[TMP2:%.*]] = icmp slt i32 [[TMP1]], 32767
125; CHECK-NEXT:    [[R:%.*]] = select i1 [[TMP2]], i32 [[TMP1]], i32 32767
126; CHECK-NEXT:    ret i32 [[R]]
127;
128  %dont_need_to_clamp_positive = icmp sle i32 %X, 32767
129  %need_to_clamp_negative = icmp sle i32 %X, -32768
130  %clamp_limit = select i1 %dont_need_to_clamp_positive, i32 -32768, i32 32767
131  %dont_need_to_clamp = xor i1 %dont_need_to_clamp_positive, %need_to_clamp_negative
132  %R = select i1 %dont_need_to_clamp, i32 %X, i32 %clamp_limit
133  ret i32 %R
134}
135