[Support] Recycler: Implement move constructor (#120555)
[llvm-project.git] / llvm / test / Transforms / InstCombine / usubo.ll
blob2074190a2cd453362b8cd1ba55cd5b5579bc56ae
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
4 declare { i64, i1 } @llvm.usub.with.overflow.i64(i64, i64)
5 declare { i8, i1 } @llvm.usub.with.overflow.i8(i8, i8)
7 declare void @use(i1)
9 define i1 @test_generic(i64 %a, i64 %b) {
10 ; CHECK-LABEL: @test_generic(
11 ; CHECK-NEXT:    [[OVERFLOW:%.*]] = icmp ult i64 [[A:%.*]], [[B:%.*]]
12 ; CHECK-NEXT:    ret i1 [[OVERFLOW]]
14   %res = tail call { i64, i1 } @llvm.usub.with.overflow.i64(i64 %a, i64 %b)
15   %overflow = extractvalue { i64, i1 } %res, 1
16   ret i1 %overflow
19 define i1 @test_constant0(i8 %a) {
20 ; CHECK-LABEL: @test_constant0(
21 ; CHECK-NEXT:    ret i1 false
23   %res = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 %a, i8 0)
24   %overflow = extractvalue { i8, i1 } %res, 1
25   ret i1 %overflow
28 define i1 @test_constant1(i8 %a) {
29 ; CHECK-LABEL: @test_constant1(
30 ; CHECK-NEXT:    [[OVERFLOW:%.*]] = icmp eq i8 [[A:%.*]], 0
31 ; CHECK-NEXT:    ret i1 [[OVERFLOW]]
33   %res = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 %a, i8 1)
34   %overflow = extractvalue { i8, i1 } %res, 1
35   ret i1 %overflow
38 define i1 @test_constant2(i8 %a) {
39 ; CHECK-LABEL: @test_constant2(
40 ; CHECK-NEXT:    [[OVERFLOW:%.*]] = icmp ult i8 [[A:%.*]], 2
41 ; CHECK-NEXT:    ret i1 [[OVERFLOW]]
43   %res = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 %a, i8 2)
44   %overflow = extractvalue { i8, i1 } %res, 1
45   ret i1 %overflow
48 define i1 @test_constant3(i8 %a) {
49 ; CHECK-LABEL: @test_constant3(
50 ; CHECK-NEXT:    [[OVERFLOW:%.*]] = icmp ult i8 [[A:%.*]], 3
51 ; CHECK-NEXT:    ret i1 [[OVERFLOW]]
53   %res = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 %a, i8 3)
54   %overflow = extractvalue { i8, i1 } %res, 1
55   ret i1 %overflow
58 define i1 @test_constant4(i8 %a) {
59 ; CHECK-LABEL: @test_constant4(
60 ; CHECK-NEXT:    [[OVERFLOW:%.*]] = icmp ult i8 [[A:%.*]], 4
61 ; CHECK-NEXT:    ret i1 [[OVERFLOW]]
63   %res = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 %a, i8 4)
64   %overflow = extractvalue { i8, i1 } %res, 1
65   ret i1 %overflow
69 define i1 @test_constant127(i8 %a) {
70 ; CHECK-LABEL: @test_constant127(
71 ; CHECK-NEXT:    [[OVERFLOW:%.*]] = icmp ult i8 [[A:%.*]], 127
72 ; CHECK-NEXT:    ret i1 [[OVERFLOW]]
74   %res = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 %a, i8 127)
75   %overflow = extractvalue { i8, i1 } %res, 1
76   ret i1 %overflow
79 define i1 @test_constant128(i8 %a) {
80 ; CHECK-LABEL: @test_constant128(
81 ; CHECK-NEXT:    [[OVERFLOW:%.*]] = icmp sgt i8 [[A:%.*]], -1
82 ; CHECK-NEXT:    ret i1 [[OVERFLOW]]
84   %res = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 %a, i8 128)
85   %overflow = extractvalue { i8, i1 } %res, 1
86   ret i1 %overflow
89 define i1 @test_constant255(i8 %a) {
90 ; CHECK-LABEL: @test_constant255(
91 ; CHECK-NEXT:    [[OVERFLOW:%.*]] = icmp ne i8 [[A:%.*]], -1
92 ; CHECK-NEXT:    ret i1 [[OVERFLOW]]
94   %res = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 %a, i8 255)
95   %overflow = extractvalue { i8, i1 } %res, 1
96   ret i1 %overflow
99 define i1 @sub_eq0(i8 %x, i8 %y, i1 %b) {
100 ; CHECK-LABEL: @sub_eq0(
101 ; CHECK-NEXT:    [[OV:%.*]] = icmp ult i8 [[X:%.*]], [[Y:%.*]]
102 ; CHECK-NEXT:    call void @use(i1 [[OV]])
103 ; CHECK-NEXT:    [[EQ0:%.*]] = icmp eq i8 [[X]], [[Y]]
104 ; CHECK-NEXT:    ret i1 [[EQ0]]
106   %us = call { i8, i1 } @llvm.usub.with.overflow.i8(i8 %x, i8 %y)
107   %ov = extractvalue { i8, i1 } %us, 1
108   call void @use(i1 %ov)
109   %sub = extractvalue { i8, i1 } %us, 0
110   %eq0 = icmp eq i8 %sub, 0
111   ret i1 %eq0
114 define i1 @sub_ne0(i8 %x, i8 %y, i1 %b) {
115 ; CHECK-LABEL: @sub_ne0(
116 ; CHECK-NEXT:    [[OV:%.*]] = icmp ult i8 [[X:%.*]], [[Y:%.*]]
117 ; CHECK-NEXT:    call void @use(i1 [[OV]])
118 ; CHECK-NEXT:    [[NE0:%.*]] = icmp ne i8 [[X]], [[Y]]
119 ; CHECK-NEXT:    ret i1 [[NE0]]
121   %us = call { i8, i1 } @llvm.usub.with.overflow.i8(i8 %x, i8 %y)
122   %ov = extractvalue { i8, i1 } %us, 1
123   call void @use(i1 %ov)
124   %sub = extractvalue { i8, i1 } %us, 0
125   %ne0 = icmp ne i8 %sub, 0
126   ret i1 %ne0
129 ; negative test - need zero
131 define i1 @sub_eq1(i8 %x, i8 %y, i1 %b) {
132 ; CHECK-LABEL: @sub_eq1(
133 ; CHECK-NEXT:    [[SS:%.*]] = call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
134 ; CHECK-NEXT:    [[OV:%.*]] = extractvalue { i8, i1 } [[SS]], 1
135 ; CHECK-NEXT:    call void @use(i1 [[OV]])
136 ; CHECK-NEXT:    [[SUB:%.*]] = extractvalue { i8, i1 } [[SS]], 0
137 ; CHECK-NEXT:    [[EQ1:%.*]] = icmp eq i8 [[SUB]], 1
138 ; CHECK-NEXT:    ret i1 [[EQ1]]
140   %ss = call { i8, i1 } @llvm.usub.with.overflow.i8(i8 %x, i8 %y)
141   %ov = extractvalue { i8, i1 } %ss, 1
142   call void @use(i1 %ov)
143   %sub = extractvalue { i8, i1 } %ss, 0
144   %eq1 = icmp eq i8 %sub, 1
145   ret i1 %eq1
148 ; negative test - need equality pred
150 define i1 @sub_sgt0(i8 %x, i8 %y, i1 %b) {
151 ; CHECK-LABEL: @sub_sgt0(
152 ; CHECK-NEXT:    [[SS:%.*]] = call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
153 ; CHECK-NEXT:    [[OV:%.*]] = extractvalue { i8, i1 } [[SS]], 1
154 ; CHECK-NEXT:    call void @use(i1 [[OV]])
155 ; CHECK-NEXT:    [[SUB:%.*]] = extractvalue { i8, i1 } [[SS]], 0
156 ; CHECK-NEXT:    [[SGT0:%.*]] = icmp sgt i8 [[SUB]], 0
157 ; CHECK-NEXT:    ret i1 [[SGT0]]
159   %ss = call { i8, i1 } @llvm.usub.with.overflow.i8(i8 %x, i8 %y)
160   %ov = extractvalue { i8, i1 } %ss, 1
161   call void @use(i1 %ov)
162   %sub = extractvalue { i8, i1 } %ss, 0
163   %sgt0 = icmp sgt i8 %sub, 0
164   ret i1 %sgt0