xref: /llvm-project/llvm/test/Transforms/InstCombine/ssubo.ll (revision e5748c6e73e7a3173046002b1f9a556965552c37)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3
4declare { i64, i1 } @llvm.ssub.with.overflow.i64(i64, i64)
5declare { i8, i1 } @llvm.ssub.with.overflow.i8(i8, i8)
6
7declare void @use(i1)
8
9define i1 @test_generic(i64 %a, i64 %b) {
10; CHECK-LABEL: @test_generic(
11; CHECK-NEXT:    [[RES:%.*]] = tail call { i64, i1 } @llvm.ssub.with.overflow.i64(i64 [[A:%.*]], i64 [[B:%.*]])
12; CHECK-NEXT:    [[OVERFLOW:%.*]] = extractvalue { i64, i1 } [[RES]], 1
13; CHECK-NEXT:    ret i1 [[OVERFLOW]]
14;
15  %res = tail call { i64, i1 } @llvm.ssub.with.overflow.i64(i64 %a, i64 %b)
16  %overflow = extractvalue { i64, i1 } %res, 1
17  ret i1 %overflow
18}
19
20define i1 @test_constant0(i8 %a) {
21; CHECK-LABEL: @test_constant0(
22; CHECK-NEXT:    ret i1 false
23;
24  %res = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %a, i8 0)
25  %overflow = extractvalue { i8, i1 } %res, 1
26  ret i1 %overflow
27}
28
29define i1 @test_constant1(i8 %a) {
30; CHECK-LABEL: @test_constant1(
31; CHECK-NEXT:    [[OVERFLOW:%.*]] = icmp eq i8 [[A:%.*]], -128
32; CHECK-NEXT:    ret i1 [[OVERFLOW]]
33;
34  %res = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %a, i8 1)
35  %overflow = extractvalue { i8, i1 } %res, 1
36  ret i1 %overflow
37}
38
39define i1 @test_constant2(i8 %a) {
40; CHECK-LABEL: @test_constant2(
41; CHECK-NEXT:    [[OVERFLOW:%.*]] = icmp slt i8 [[A:%.*]], -126
42; CHECK-NEXT:    ret i1 [[OVERFLOW]]
43;
44  %res = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %a, i8 2)
45  %overflow = extractvalue { i8, i1 } %res, 1
46  ret i1 %overflow
47}
48
49define i1 @test_constant3(i8 %a) {
50; CHECK-LABEL: @test_constant3(
51; CHECK-NEXT:    [[OVERFLOW:%.*]] = icmp slt i8 [[A:%.*]], -125
52; CHECK-NEXT:    ret i1 [[OVERFLOW]]
53;
54  %res = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %a, i8 3)
55  %overflow = extractvalue { i8, i1 } %res, 1
56  ret i1 %overflow
57}
58
59define i1 @test_constant4(i8 %a) {
60; CHECK-LABEL: @test_constant4(
61; CHECK-NEXT:    [[OVERFLOW:%.*]] = icmp slt i8 [[A:%.*]], -124
62; CHECK-NEXT:    ret i1 [[OVERFLOW]]
63;
64  %res = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %a, i8 4)
65  %overflow = extractvalue { i8, i1 } %res, 1
66  ret i1 %overflow
67}
68
69
70define i1 @test_constant127(i8 %a) {
71; CHECK-LABEL: @test_constant127(
72; CHECK-NEXT:    [[OVERFLOW:%.*]] = icmp slt i8 [[A:%.*]], -1
73; CHECK-NEXT:    ret i1 [[OVERFLOW]]
74;
75  %res = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %a, i8 127)
76  %overflow = extractvalue { i8, i1 } %res, 1
77  ret i1 %overflow
78}
79
80define i1 @test_constant128(i8 %a) {
81; CHECK-LABEL: @test_constant128(
82; CHECK-NEXT:    [[OVERFLOW:%.*]] = icmp sgt i8 [[A:%.*]], -1
83; CHECK-NEXT:    ret i1 [[OVERFLOW]]
84;
85  %res = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %a, i8 128)
86  %overflow = extractvalue { i8, i1 } %res, 1
87  ret i1 %overflow
88}
89
90define i1 @test_constant255(i8 %a) {
91; CHECK-LABEL: @test_constant255(
92; CHECK-NEXT:    [[OVERFLOW:%.*]] = icmp eq i8 [[A:%.*]], 127
93; CHECK-NEXT:    ret i1 [[OVERFLOW]]
94;
95  %res = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %a, i8 255)
96  %overflow = extractvalue { i8, i1 } %res, 1
97  ret i1 %overflow
98}
99
100define i1 @sub_eq0(i8 %x, i8 %y, i1 %b) {
101; CHECK-LABEL: @sub_eq0(
102; CHECK-NEXT:    [[SS:%.*]] = call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
103; CHECK-NEXT:    [[OV:%.*]] = extractvalue { i8, i1 } [[SS]], 1
104; CHECK-NEXT:    call void @use(i1 [[OV]])
105; CHECK-NEXT:    [[EQ0:%.*]] = icmp eq i8 [[X]], [[Y]]
106; CHECK-NEXT:    ret i1 [[EQ0]]
107;
108  %ss = call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %x, i8 %y)
109  %ov = extractvalue { i8, i1 } %ss, 1
110  call void @use(i1 %ov)
111  %sub = extractvalue { i8, i1 } %ss, 0
112  %eq0 = icmp eq i8 %sub, 0
113  ret i1 %eq0
114}
115
116define i1 @sub_ne0(i8 %x, i8 %y, i1 %b) {
117; CHECK-LABEL: @sub_ne0(
118; CHECK-NEXT:    [[SS:%.*]] = call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
119; CHECK-NEXT:    [[OV:%.*]] = extractvalue { i8, i1 } [[SS]], 1
120; CHECK-NEXT:    call void @use(i1 [[OV]])
121; CHECK-NEXT:    [[NE0:%.*]] = icmp ne i8 [[X]], [[Y]]
122; CHECK-NEXT:    ret i1 [[NE0]]
123;
124  %ss = call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %x, i8 %y)
125  %ov = extractvalue { i8, i1 } %ss, 1
126  call void @use(i1 %ov)
127  %sub = extractvalue { i8, i1 } %ss, 0
128  %ne0 = icmp ne i8 %sub, 0
129  ret i1 %ne0
130}
131
132; negative test - need zero
133
134define i1 @sub_eq1(i8 %x, i8 %y, i1 %b) {
135; CHECK-LABEL: @sub_eq1(
136; CHECK-NEXT:    [[SS:%.*]] = call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
137; CHECK-NEXT:    [[OV:%.*]] = extractvalue { i8, i1 } [[SS]], 1
138; CHECK-NEXT:    call void @use(i1 [[OV]])
139; CHECK-NEXT:    [[SUB:%.*]] = extractvalue { i8, i1 } [[SS]], 0
140; CHECK-NEXT:    [[EQ1:%.*]] = icmp eq i8 [[SUB]], 1
141; CHECK-NEXT:    ret i1 [[EQ1]]
142;
143  %ss = call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %x, i8 %y)
144  %ov = extractvalue { i8, i1 } %ss, 1
145  call void @use(i1 %ov)
146  %sub = extractvalue { i8, i1 } %ss, 0
147  %eq1 = icmp eq i8 %sub, 1
148  ret i1 %eq1
149}
150
151; negative test - need equality pred
152
153define i1 @sub_sgt0(i8 %x, i8 %y, i1 %b) {
154; CHECK-LABEL: @sub_sgt0(
155; CHECK-NEXT:    [[SS:%.*]] = call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
156; CHECK-NEXT:    [[OV:%.*]] = extractvalue { i8, i1 } [[SS]], 1
157; CHECK-NEXT:    call void @use(i1 [[OV]])
158; CHECK-NEXT:    [[SUB:%.*]] = extractvalue { i8, i1 } [[SS]], 0
159; CHECK-NEXT:    [[SGT0:%.*]] = icmp sgt i8 [[SUB]], 0
160; CHECK-NEXT:    ret i1 [[SGT0]]
161;
162  %ss = call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %x, i8 %y)
163  %ov = extractvalue { i8, i1 } %ss, 1
164  call void @use(i1 %ov)
165  %sub = extractvalue { i8, i1 } %ss, 0
166  %sgt0 = icmp sgt i8 %sub, 0
167  ret i1 %sgt0
168}
169