307 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s3 4declare { i8, i1 } @llvm.usub.with.overflow.i8(i8, i8)5 6define i8 @usub_no_overflow_due_to_cmp_condition(i8 %a, i8 %b) {7; CHECK-LABEL: @usub_no_overflow_due_to_cmp_condition(8; CHECK-NEXT: entry:9; CHECK-NEXT: [[C_1:%.*]] = icmp uge i8 [[B:%.*]], [[A:%.*]]10; CHECK-NEXT: br i1 [[C_1]], label [[MATH:%.*]], label [[EXIT_FAIL:%.*]]11; CHECK: math:12; CHECK-NEXT: [[OP:%.*]] = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[B]], i8 [[A]])13; CHECK-NEXT: [[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 114; CHECK-NEXT: br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]]15; CHECK: exit.ok:16; CHECK-NEXT: [[RES:%.*]] = extractvalue { i8, i1 } [[OP]], 017; CHECK-NEXT: ret i8 [[RES]]18; CHECK: exit.fail:19; CHECK-NEXT: ret i8 020;21entry:22 %c.1 = icmp uge i8 %b, %a23 br i1 %c.1, label %math, label %exit.fail24 25math:26 %op = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 %b, i8 %a)27 %status = extractvalue { i8, i1 } %op, 128 br i1 %status, label %exit.fail, label %exit.ok29 30exit.ok:31 %res = extractvalue { i8, i1 } %op, 032 ret i8 %res33 34exit.fail:35 ret i8 036}37 38define i8 @usub_no_overflow_due_to_cmp_condition2(i8 %a, i8 %b) {39; CHECK-LABEL: @usub_no_overflow_due_to_cmp_condition2(40; CHECK-NEXT: entry:41; CHECK-NEXT: [[C_1:%.*]] = icmp ule i8 [[B:%.*]], [[A:%.*]]42; CHECK-NEXT: br i1 [[C_1]], label [[EXIT_FAIL:%.*]], label [[MATH:%.*]]43; CHECK: math:44; CHECK-NEXT: [[OP:%.*]] = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[B]], i8 [[A]])45; CHECK-NEXT: [[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 146; CHECK-NEXT: br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]]47; CHECK: exit.ok:48; CHECK-NEXT: [[RES:%.*]] = extractvalue { i8, i1 } [[OP]], 049; CHECK-NEXT: ret i8 [[RES]]50; CHECK: exit.fail:51; CHECK-NEXT: ret i8 052;53entry:54 %c.1 = icmp ule i8 %b, %a55 br i1 %c.1, label %exit.fail, label %math56 57math:58 %op = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 %b, i8 %a)59 %status = extractvalue { i8, i1 } %op, 160 br i1 %status, label %exit.fail, label %exit.ok61 62exit.ok:63 %res = extractvalue { i8, i1 } %op, 064 ret i8 %res65 66exit.fail:67 ret i8 068}69 70declare void @use_res({ i8, i1 })71 72define i8 @sub_no_overflow_due_to_cmp_condition_result_used(i8 %a, i8 %b) {73; CHECK-LABEL: @sub_no_overflow_due_to_cmp_condition_result_used(74; CHECK-NEXT: entry:75; CHECK-NEXT: [[C_1:%.*]] = icmp ule i8 [[B:%.*]], [[A:%.*]]76; CHECK-NEXT: br i1 [[C_1]], label [[EXIT_FAIL:%.*]], label [[MATH:%.*]]77; CHECK: math:78; CHECK-NEXT: [[OP:%.*]] = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[B]], i8 [[A]])79; CHECK-NEXT: call void @use_res({ i8, i1 } [[OP]])80; CHECK-NEXT: [[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 181; CHECK-NEXT: br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]]82; CHECK: exit.ok:83; CHECK-NEXT: [[RES:%.*]] = extractvalue { i8, i1 } [[OP]], 084; CHECK-NEXT: ret i8 [[RES]]85; CHECK: exit.fail:86; CHECK-NEXT: ret i8 087;88entry:89 %c.1 = icmp ule i8 %b, %a90 br i1 %c.1, label %exit.fail, label %math91 92math:93 %op = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 %b, i8 %a)94 call void @use_res({ i8, i1 } %op)95 %status = extractvalue { i8, i1 } %op, 196 br i1 %status, label %exit.fail, label %exit.ok97 98exit.ok:99 %res = extractvalue { i8, i1 } %op, 0100 ret i8 %res101 102exit.fail:103 ret i8 0104}105 106define i8 @usub_no_overflow_due_to_or_conds(i8 %a, i8 %b) {107; CHECK-LABEL: @usub_no_overflow_due_to_or_conds(108; CHECK-NEXT: entry:109; CHECK-NEXT: [[C_1:%.*]] = icmp ule i8 [[B:%.*]], [[A:%.*]]110; CHECK-NEXT: [[C_2:%.*]] = icmp ule i8 [[A]], 0111; CHECK-NEXT: [[OR:%.*]] = or i1 [[C_2]], [[C_1]]112; CHECK-NEXT: br i1 [[OR]], label [[EXIT_FAIL:%.*]], label [[MATH:%.*]]113; CHECK: math:114; CHECK-NEXT: [[OP:%.*]] = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[B]], i8 [[A]])115; CHECK-NEXT: [[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 1116; CHECK-NEXT: br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]]117; CHECK: exit.ok:118; CHECK-NEXT: [[RES:%.*]] = extractvalue { i8, i1 } [[OP]], 0119; CHECK-NEXT: ret i8 [[RES]]120; CHECK: exit.fail:121; CHECK-NEXT: ret i8 0122;123entry:124 %c.1 = icmp ule i8 %b, %a125 %c.2 = icmp ule i8 %a, 0126 %or = or i1 %c.2, %c.1127 br i1 %or, label %exit.fail, label %math128 129math:130 %op = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 %b, i8 %a)131 %status = extractvalue { i8, i1 } %op, 1132 br i1 %status, label %exit.fail, label %exit.ok133 134exit.ok:135 %res = extractvalue { i8, i1 } %op, 0136 ret i8 %res137 138exit.fail:139 ret i8 0140}141 142define i8 @usub_no_overflow_due_to_or_conds_sub_result_not_used(i8 %a, i8 %b) {143; CHECK-LABEL: @usub_no_overflow_due_to_or_conds_sub_result_not_used(144; CHECK-NEXT: entry:145; CHECK-NEXT: [[C_1:%.*]] = icmp ule i8 [[B:%.*]], [[A:%.*]]146; CHECK-NEXT: [[C_2:%.*]] = icmp ule i8 [[A]], 0147; CHECK-NEXT: [[OR:%.*]] = or i1 [[C_2]], [[C_1]]148; CHECK-NEXT: br i1 [[OR]], label [[EXIT_FAIL:%.*]], label [[MATH:%.*]]149; CHECK: math:150; CHECK-NEXT: [[OP:%.*]] = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[B]], i8 [[A]])151; CHECK-NEXT: [[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 1152; CHECK-NEXT: br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]]153; CHECK: exit.ok:154; CHECK-NEXT: ret i8 20155; CHECK: exit.fail:156; CHECK-NEXT: ret i8 0157;158entry:159 %c.1 = icmp ule i8 %b, %a160 %c.2 = icmp ule i8 %a, 0161 %or = or i1 %c.2, %c.1162 br i1 %or, label %exit.fail, label %math163 164math:165 %op = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 %b, i8 %a)166 %status = extractvalue { i8, i1 } %op, 1167 br i1 %status, label %exit.fail, label %exit.ok168 169exit.ok:170 ret i8 20171 172exit.fail:173 ret i8 0174}175 176define i8 @usub_no_overflow_due_to_and_conds(i8 %a, i8 %b) {177; CHECK-LABEL: @usub_no_overflow_due_to_and_conds(178; CHECK-NEXT: entry:179; CHECK-NEXT: [[C_1:%.*]] = icmp uge i8 [[B:%.*]], [[A:%.*]]180; CHECK-NEXT: [[C_2:%.*]] = icmp uge i8 [[A]], -1181; CHECK-NEXT: [[AND:%.*]] = and i1 [[C_2]], [[C_1]]182; CHECK-NEXT: br i1 [[AND]], label [[MATH:%.*]], label [[EXIT_FAIL:%.*]]183; CHECK: math:184; CHECK-NEXT: [[OP:%.*]] = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[B]], i8 [[A]])185; CHECK-NEXT: [[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 1186; CHECK-NEXT: br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]]187; CHECK: exit.ok:188; CHECK-NEXT: [[RES:%.*]] = extractvalue { i8, i1 } [[OP]], 0189; CHECK-NEXT: ret i8 [[RES]]190; CHECK: exit.fail:191; CHECK-NEXT: ret i8 0192;193entry:194 %c.1 = icmp uge i8 %b, %a195 %c.2 = icmp uge i8 %a, -1196 %and = and i1 %c.2, %c.1197 br i1 %and, label %math, label %exit.fail198 199math:200 %op = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 %b, i8 %a)201 %status = extractvalue { i8, i1 } %op, 1202 br i1 %status, label %exit.fail, label %exit.ok203 204exit.ok:205 %res = extractvalue { i8, i1 } %op, 0206 ret i8 %res207 208exit.fail:209 ret i8 0210}211 212define i8 @usub_may_overflow1(i8 %a, i8 %b) {213; CHECK-LABEL: @usub_may_overflow1(214; CHECK-NEXT: entry:215; CHECK-NEXT: br i1 true, label [[MATH:%.*]], label [[EXIT_FAIL:%.*]]216; CHECK: math:217; CHECK-NEXT: [[OP:%.*]] = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[B:%.*]], i8 [[A:%.*]])218; CHECK-NEXT: [[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 1219; CHECK-NEXT: br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]]220; CHECK: exit.ok:221; CHECK-NEXT: [[RES:%.*]] = extractvalue { i8, i1 } [[OP]], 0222; CHECK-NEXT: ret i8 [[RES]]223; CHECK: exit.fail:224; CHECK-NEXT: ret i8 0225;226entry:227 %c.1 = icmp uge i8 %a, 0228 br i1 %c.1, label %math, label %exit.fail229 230math:231 %op = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 %b, i8 %a)232 %status = extractvalue { i8, i1 } %op, 1233 br i1 %status, label %exit.fail, label %exit.ok234 235exit.ok:236 %res = extractvalue { i8, i1 } %op, 0237 ret i8 %res238 239exit.fail:240 ret i8 0241}242 243 244define i8 @usub_may_overflow2(i8 %a, i8 %b) {245; CHECK-LABEL: @usub_may_overflow2(246; CHECK-NEXT: entry:247; CHECK-NEXT: [[C_1:%.*]] = icmp sge i8 [[B:%.*]], [[A:%.*]]248; CHECK-NEXT: br i1 [[C_1]], label [[MATH:%.*]], label [[EXIT_FAIL:%.*]]249; CHECK: math:250; CHECK-NEXT: [[OP:%.*]] = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[B]], i8 [[A]])251; CHECK-NEXT: [[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 1252; CHECK-NEXT: br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]]253; CHECK: exit.ok:254; CHECK-NEXT: [[RES:%.*]] = extractvalue { i8, i1 } [[OP]], 0255; CHECK-NEXT: ret i8 [[RES]]256; CHECK: exit.fail:257; CHECK-NEXT: ret i8 0258;259entry:260 %c.1 = icmp sge i8 %b, %a261 br i1 %c.1, label %math, label %exit.fail262 263math:264 %op = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 %b, i8 %a)265 %status = extractvalue { i8, i1 } %op, 1266 br i1 %status, label %exit.fail, label %exit.ok267 268exit.ok:269 %res = extractvalue { i8, i1 } %op, 0270 ret i8 %res271 272exit.fail:273 ret i8 0274}275 276define i8 @usub_may_overflow3(i8 %a, i8 %b) {277; CHECK-LABEL: @usub_may_overflow3(278; CHECK-NEXT: entry:279; CHECK-NEXT: [[C_1:%.*]] = icmp slt i8 [[B:%.*]], [[A:%.*]]280; CHECK-NEXT: br i1 [[C_1]], label [[EXIT_FAIL:%.*]], label [[MATH:%.*]]281; CHECK: math:282; CHECK-NEXT: [[OP:%.*]] = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[B]], i8 [[A]])283; CHECK-NEXT: [[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 1284; CHECK-NEXT: br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]]285; CHECK: exit.ok:286; CHECK-NEXT: [[RES:%.*]] = extractvalue { i8, i1 } [[OP]], 0287; CHECK-NEXT: ret i8 [[RES]]288; CHECK: exit.fail:289; CHECK-NEXT: ret i8 0290;291entry:292 %c.1 = icmp slt i8 %b, %a293 br i1 %c.1, label %exit.fail, label %math294math:295 %op = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 %b, i8 %a)296 %status = extractvalue { i8, i1 } %op, 1297 br i1 %status, label %exit.fail, label %exit.ok298 299exit.ok:300 %res = extractvalue { i8, i1 } %op, 0301 ret i8 %res302 303exit.fail:304 ret i8 0305}306 307