xref: /llvm-project/llvm/test/Transforms/SCCP/ip-ranges-binaryops.ll (revision 7d10213317c18e1d24753e5532d2b037db2d2c5c)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=ipsccp -S | FileCheck %s
3
4; x = [10, 21), y = [100, 201)
5; x + y = [110, 221)
6define internal i1 @f.add(i32 %x, i32 %y) {
7; CHECK-LABEL: @f.add(
8; CHECK-NEXT:    [[A_1:%.*]] = add nuw nsw i32 [[X:%.*]], [[Y:%.*]]
9; CHECK-NEXT:    [[C_2:%.*]] = icmp sgt i32 [[A_1]], 219
10; CHECK-NEXT:    [[C_4:%.*]] = icmp slt i32 [[A_1]], 111
11; CHECK-NEXT:    [[C_5:%.*]] = icmp eq i32 [[A_1]], 150
12; CHECK-NEXT:    [[C_6:%.*]] = icmp slt i32 [[A_1]], 150
13; CHECK-NEXT:    [[RES_1:%.*]] = add nuw nsw i1 false, [[C_2]]
14; CHECK-NEXT:    [[RES_2:%.*]] = add nuw nsw i1 [[RES_1]], false
15; CHECK-NEXT:    [[RES_3:%.*]] = add i1 [[RES_2]], [[C_4]]
16; CHECK-NEXT:    [[RES_4:%.*]] = add i1 [[RES_3]], [[C_5]]
17; CHECK-NEXT:    [[RES_5:%.*]] = add i1 [[RES_4]], [[C_6]]
18; CHECK-NEXT:    ret i1 [[RES_5]]
19;
20  %a.1 = add i32 %x, %y
21  %c.1 = icmp sgt i32 %a.1, 220
22  %c.2 = icmp sgt i32 %a.1, 219
23  %c.3 = icmp slt i32 %a.1, 110
24  %c.4 = icmp slt i32 %a.1, 111
25  %c.5 = icmp eq i32 %a.1, 150
26  %c.6 = icmp slt i32 %a.1, 150
27  %res.1 = add i1 %c.1, %c.2
28  %res.2 = add i1 %res.1, %c.3
29  %res.3 = add i1 %res.2, %c.4
30  %res.4 = add i1 %res.3, %c.5
31  %res.5 = add i1 %res.4, %c.6
32  ret i1 %res.5
33}
34
35define i1 @caller.add() {
36; CHECK-LABEL: @caller.add(
37; CHECK-NEXT:    [[CALL_1:%.*]] = tail call i1 @f.add(i32 10, i32 100)
38; CHECK-NEXT:    [[CALL_2:%.*]] = tail call i1 @f.add(i32 20, i32 200)
39; CHECK-NEXT:    [[RES:%.*]] = and i1 [[CALL_1]], [[CALL_2]]
40; CHECK-NEXT:    ret i1 [[RES]]
41;
42  %call.1 = tail call i1 @f.add(i32 10, i32 100)
43  %call.2 = tail call i1 @f.add(i32 20, i32 200)
44  %res = and i1 %call.1, %call.2
45  ret i1 %res
46}
47
48
49; x = [10, 21), y = [100, 201)
50; x - y = [-190, -79)
51define internal i1 @f.sub(i32 %x, i32 %y) {
52; CHECK-LABEL: @f.sub(
53; CHECK-NEXT:    [[A_1:%.*]] = sub nsw i32 [[X:%.*]], [[Y:%.*]]
54; CHECK-NEXT:    [[C_2:%.*]] = icmp sgt i32 [[A_1]], -81
55; CHECK-NEXT:    [[C_4:%.*]] = icmp slt i32 [[A_1]], -189
56; CHECK-NEXT:    [[C_5:%.*]] = icmp eq i32 [[A_1]], -150
57; CHECK-NEXT:    [[C_6:%.*]] = icmp slt i32 [[A_1]], -150
58; CHECK-NEXT:    [[RES_1:%.*]] = add nuw nsw i1 false, [[C_2]]
59; CHECK-NEXT:    [[RES_2:%.*]] = add nuw nsw i1 [[RES_1]], false
60; CHECK-NEXT:    [[RES_3:%.*]] = add i1 [[RES_2]], [[C_4]]
61; CHECK-NEXT:    [[RES_4:%.*]] = add i1 [[RES_3]], [[C_5]]
62; CHECK-NEXT:    [[RES_5:%.*]] = add i1 [[RES_4]], [[C_6]]
63; CHECK-NEXT:    ret i1 [[RES_5]]
64;
65  %a.1 = sub i32 %x, %y
66  %c.1 = icmp sgt i32 %a.1, -80
67  %c.2 = icmp sgt i32 %a.1, -81
68  %c.3 = icmp slt i32 %a.1, -190
69  %c.4 = icmp slt i32 %a.1, -189
70  %c.5 = icmp eq i32 %a.1, -150
71  %c.6 = icmp slt i32 %a.1, -150
72  %res.1 = add i1 %c.1, %c.2
73  %res.2 = add i1 %res.1, %c.3
74  %res.3 = add i1 %res.2, %c.4
75  %res.4 = add i1 %res.3, %c.5
76  %res.5 = add i1 %res.4, %c.6
77  ret i1 %res.5
78}
79
80define i1 @caller.sub() {
81; CHECK-LABEL: @caller.sub(
82; CHECK-NEXT:    [[CALL_1:%.*]] = tail call i1 @f.sub(i32 10, i32 100)
83; CHECK-NEXT:    [[CALL_2:%.*]] = tail call i1 @f.sub(i32 20, i32 200)
84; CHECK-NEXT:    [[RES:%.*]] = and i1 [[CALL_1]], [[CALL_2]]
85; CHECK-NEXT:    ret i1 [[RES]]
86;
87  %call.1 = tail call i1 @f.sub(i32 10, i32 100)
88  %call.2 = tail call i1 @f.sub(i32 20, i32 200)
89  %res = and i1 %call.1, %call.2
90  ret i1 %res
91}
92
93; x = [10, 21), y = [100, 201)
94; x * y = [1000, 4001)
95define internal i1 @f.mul(i32 %x, i32 %y) {
96; CHECK-LABEL: @f.mul(
97; CHECK-NEXT:    [[A_1:%.*]] = mul nuw nsw i32 [[X:%.*]], [[Y:%.*]]
98; CHECK-NEXT:    [[C_2:%.*]] = icmp sgt i32 [[A_1]], 3999
99; CHECK-NEXT:    [[C_4:%.*]] = icmp slt i32 [[A_1]], 1001
100; CHECK-NEXT:    [[C_5:%.*]] = icmp eq i32 [[A_1]], 1500
101; CHECK-NEXT:    [[C_6:%.*]] = icmp slt i32 [[A_1]], 1500
102; CHECK-NEXT:    [[RES_1:%.*]] = add nuw nsw i1 false, [[C_2]]
103; CHECK-NEXT:    [[RES_2:%.*]] = add nuw nsw i1 [[RES_1]], false
104; CHECK-NEXT:    [[RES_3:%.*]] = add i1 [[RES_2]], [[C_4]]
105; CHECK-NEXT:    [[RES_4:%.*]] = add i1 [[RES_3]], [[C_5]]
106; CHECK-NEXT:    [[RES_5:%.*]] = add i1 [[RES_4]], [[C_6]]
107; CHECK-NEXT:    ret i1 [[RES_5]]
108;
109  %a.1 = mul i32 %x, %y
110  %c.1 = icmp sgt i32 %a.1, 4000
111  %c.2 = icmp sgt i32 %a.1, 3999
112  %c.3 = icmp slt i32 %a.1, 1000
113  %c.4 = icmp slt i32 %a.1, 1001
114  %c.5 = icmp eq i32 %a.1, 1500
115  %c.6 = icmp slt i32 %a.1, 1500
116  %res.1 = add i1 %c.1, %c.2
117  %res.2 = add i1 %res.1, %c.3
118  %res.3 = add i1 %res.2, %c.4
119  %res.4 = add i1 %res.3, %c.5
120  %res.5 = add i1 %res.4, %c.6
121  ret i1 %res.5
122}
123
124define i1 @caller.mul() {
125; CHECK-LABEL: @caller.mul(
126; CHECK-NEXT:    [[CALL_1:%.*]] = tail call i1 @f.mul(i32 10, i32 100)
127; CHECK-NEXT:    [[CALL_2:%.*]] = tail call i1 @f.mul(i32 20, i32 200)
128; CHECK-NEXT:    [[RES:%.*]] = and i1 [[CALL_1]], [[CALL_2]]
129; CHECK-NEXT:    ret i1 [[RES]]
130;
131  %call.1 = tail call i1 @f.mul(i32 10, i32 100)
132  %call.2 = tail call i1 @f.mul(i32 20, i32 200)
133  %res = and i1 %call.1, %call.2
134  ret i1 %res
135}
136