671 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -S -passes=correlated-propagation < %s | FileCheck %s3 4declare void @llvm.trap()5declare {i8, i1} @llvm.uadd.with.overflow(i8, i8)6declare {i8, i1} @llvm.sadd.with.overflow(i8, i8)7declare {i8, i1} @llvm.usub.with.overflow(i8, i8)8declare {i8, i1} @llvm.ssub.with.overflow(i8, i8)9declare {i8, i1} @llvm.umul.with.overflow(i8, i8)10declare {i8, i1} @llvm.smul.with.overflow(i8, i8)11 12define i1 @uadd_ov_false(i8 %x, ptr %px, ptr %pc) {13; CHECK-LABEL: @uadd_ov_false(14; CHECK-NEXT: [[VAL_OV:%.*]] = call { i8, i1 } @llvm.uadd.with.overflow.i8(i8 [[X:%.*]], i8 100)15; CHECK-NEXT: [[VAL:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 016; CHECK-NEXT: store i8 [[VAL]], ptr [[PX:%.*]], align 117; CHECK-NEXT: [[OV:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 118; CHECK-NEXT: br i1 [[OV]], label [[TRAP:%.*]], label [[NO_OVERFLOW:%.*]]19; CHECK: no_overflow:20; CHECK-NEXT: [[C1:%.*]] = icmp ugt i8 [[X]], -10221; CHECK-NEXT: store i1 [[C1]], ptr [[PC:%.*]], align 122; CHECK-NEXT: ret i1 false23; CHECK: trap:24; CHECK-NEXT: call void @llvm.trap()25; CHECK-NEXT: unreachable26;27 %val_ov = call {i8, i1} @llvm.uadd.with.overflow(i8 %x, i8 100)28 %val = extractvalue {i8, i1} %val_ov, 029 store i8 %val, ptr %px30 %ov = extractvalue {i8, i1} %val_ov, 131 br i1 %ov, label %trap, label %no_overflow32 33no_overflow:34 %c1 = icmp ugt i8 %x, 15435 store i1 %c1, ptr %pc36 %c2 = icmp ugt i8 %x, 15537 ret i1 %c238 39trap:40 call void @llvm.trap()41 unreachable42}43 44define i1 @uadd_ov_true(i8 %x, ptr %px, ptr %pc) {45; CHECK-LABEL: @uadd_ov_true(46; CHECK-NEXT: [[VAL_OV:%.*]] = call { i8, i1 } @llvm.uadd.with.overflow.i8(i8 [[X:%.*]], i8 100)47; CHECK-NEXT: [[VAL:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 048; CHECK-NEXT: store i8 [[VAL]], ptr [[PX:%.*]], align 149; CHECK-NEXT: [[OV:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 150; CHECK-NEXT: br i1 [[OV]], label [[OVERFLOW:%.*]], label [[TRAP:%.*]]51; CHECK: overflow:52; CHECK-NEXT: [[C1:%.*]] = icmp samesign ugt i8 [[X]], -10053; CHECK-NEXT: store i1 [[C1]], ptr [[PC:%.*]], align 154; CHECK-NEXT: ret i1 true55; CHECK: trap:56; CHECK-NEXT: call void @llvm.trap()57; CHECK-NEXT: unreachable58;59 %val_ov = call {i8, i1} @llvm.uadd.with.overflow(i8 %x, i8 100)60 %val = extractvalue {i8, i1} %val_ov, 061 store i8 %val, ptr %px62 %ov = extractvalue {i8, i1} %val_ov, 163 br i1 %ov, label %overflow, label %trap64 65overflow:66 %c1 = icmp ugt i8 %x, 15667 store i1 %c1, ptr %pc68 %c2 = icmp ugt i8 %x, 15569 ret i1 %c270 71trap:72 call void @llvm.trap()73 unreachable74}75 76define i1 @sadd_ov_false(i8 %x, ptr %px, ptr %pc) {77; CHECK-LABEL: @sadd_ov_false(78; CHECK-NEXT: [[VAL_OV:%.*]] = call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[X:%.*]], i8 100)79; CHECK-NEXT: [[VAL:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 080; CHECK-NEXT: store i8 [[VAL]], ptr [[PX:%.*]], align 181; CHECK-NEXT: [[OV:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 182; CHECK-NEXT: br i1 [[OV]], label [[TRAP:%.*]], label [[NO_OVERFLOW:%.*]]83; CHECK: no_overflow:84; CHECK-NEXT: [[C1:%.*]] = icmp sgt i8 [[X]], 2685; CHECK-NEXT: store i1 [[C1]], ptr [[PC:%.*]], align 186; CHECK-NEXT: ret i1 false87; CHECK: trap:88; CHECK-NEXT: call void @llvm.trap()89; CHECK-NEXT: unreachable90;91 %val_ov = call {i8, i1} @llvm.sadd.with.overflow(i8 %x, i8 100)92 %val = extractvalue {i8, i1} %val_ov, 093 store i8 %val, ptr %px94 %ov = extractvalue {i8, i1} %val_ov, 195 br i1 %ov, label %trap, label %no_overflow96 97no_overflow:98 %c1 = icmp sgt i8 %x, 2699 store i1 %c1, ptr %pc100 %c2 = icmp sgt i8 %x, 27101 ret i1 %c2102 103trap:104 call void @llvm.trap()105 unreachable106}107 108define i1 @sadd_ov_true(i8 %x, ptr %px, ptr %pc) {109; CHECK-LABEL: @sadd_ov_true(110; CHECK-NEXT: [[VAL_OV:%.*]] = call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[X:%.*]], i8 100)111; CHECK-NEXT: [[VAL:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 0112; CHECK-NEXT: store i8 [[VAL]], ptr [[PX:%.*]], align 1113; CHECK-NEXT: [[OV:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 1114; CHECK-NEXT: br i1 [[OV]], label [[OVERFLOW:%.*]], label [[TRAP:%.*]]115; CHECK: overflow:116; CHECK-NEXT: [[C1:%.*]] = icmp samesign ugt i8 [[X]], 28117; CHECK-NEXT: store i1 [[C1]], ptr [[PC:%.*]], align 1118; CHECK-NEXT: ret i1 true119; CHECK: trap:120; CHECK-NEXT: call void @llvm.trap()121; CHECK-NEXT: unreachable122;123 %val_ov = call {i8, i1} @llvm.sadd.with.overflow(i8 %x, i8 100)124 %val = extractvalue {i8, i1} %val_ov, 0125 store i8 %val, ptr %px126 %ov = extractvalue {i8, i1} %val_ov, 1127 br i1 %ov, label %overflow, label %trap128 129overflow:130 %c1 = icmp sgt i8 %x, 28131 store i1 %c1, ptr %pc132 %c2 = icmp sgt i8 %x, 27133 ret i1 %c2134 135trap:136 call void @llvm.trap()137 unreachable138}139 140define i1 @usub_ov_false(i8 %x, ptr %px, ptr %pc) {141; CHECK-LABEL: @usub_ov_false(142; CHECK-NEXT: [[VAL_OV:%.*]] = call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[X:%.*]], i8 100)143; CHECK-NEXT: [[VAL:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 0144; CHECK-NEXT: store i8 [[VAL]], ptr [[PX:%.*]], align 1145; CHECK-NEXT: [[OV:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 1146; CHECK-NEXT: br i1 [[OV]], label [[TRAP:%.*]], label [[NO_OVERFLOW:%.*]]147; CHECK: no_overflow:148; CHECK-NEXT: [[C1:%.*]] = icmp ult i8 [[X]], 101149; CHECK-NEXT: store i1 [[C1]], ptr [[PC:%.*]], align 1150; CHECK-NEXT: ret i1 false151; CHECK: trap:152; CHECK-NEXT: call void @llvm.trap()153; CHECK-NEXT: unreachable154;155 %val_ov = call {i8, i1} @llvm.usub.with.overflow(i8 %x, i8 100)156 %val = extractvalue {i8, i1} %val_ov, 0157 store i8 %val, ptr %px158 %ov = extractvalue {i8, i1} %val_ov, 1159 br i1 %ov, label %trap, label %no_overflow160 161no_overflow:162 %c1 = icmp ult i8 %x, 101163 store i1 %c1, ptr %pc164 %c2 = icmp ult i8 %x, 100165 ret i1 %c2166 167trap:168 call void @llvm.trap()169 unreachable170}171 172define i1 @usub_ov_true(i8 %x, ptr %px, ptr %pc) {173; CHECK-LABEL: @usub_ov_true(174; CHECK-NEXT: [[VAL_OV:%.*]] = call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[X:%.*]], i8 100)175; CHECK-NEXT: [[VAL:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 0176; CHECK-NEXT: store i8 [[VAL]], ptr [[PX:%.*]], align 1177; CHECK-NEXT: [[OV:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 1178; CHECK-NEXT: br i1 [[OV]], label [[OVERFLOW:%.*]], label [[TRAP:%.*]]179; CHECK: overflow:180; CHECK-NEXT: [[C1:%.*]] = icmp samesign ult i8 [[X]], 99181; CHECK-NEXT: store i1 [[C1]], ptr [[PC:%.*]], align 1182; CHECK-NEXT: ret i1 true183; CHECK: trap:184; CHECK-NEXT: call void @llvm.trap()185; CHECK-NEXT: unreachable186;187 %val_ov = call {i8, i1} @llvm.usub.with.overflow(i8 %x, i8 100)188 %val = extractvalue {i8, i1} %val_ov, 0189 store i8 %val, ptr %px190 %ov = extractvalue {i8, i1} %val_ov, 1191 br i1 %ov, label %overflow, label %trap192 193overflow:194 %c1 = icmp ult i8 %x, 99195 store i1 %c1, ptr %pc196 %c2 = icmp ult i8 %x, 100197 ret i1 %c2198 199trap:200 call void @llvm.trap()201 unreachable202}203 204define i1 @ssub_ov_false(i8 %x, ptr %px, ptr %pc) {205; CHECK-LABEL: @ssub_ov_false(206; CHECK-NEXT: [[VAL_OV:%.*]] = call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[X:%.*]], i8 100)207; CHECK-NEXT: [[VAL:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 0208; CHECK-NEXT: store i8 [[VAL]], ptr [[PX:%.*]], align 1209; CHECK-NEXT: [[OV:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 1210; CHECK-NEXT: br i1 [[OV]], label [[TRAP:%.*]], label [[NO_OVERFLOW:%.*]]211; CHECK: no_overflow:212; CHECK-NEXT: [[C1:%.*]] = icmp slt i8 [[X]], -27213; CHECK-NEXT: store i1 [[C1]], ptr [[PC:%.*]], align 1214; CHECK-NEXT: ret i1 false215; CHECK: trap:216; CHECK-NEXT: call void @llvm.trap()217; CHECK-NEXT: unreachable218;219 %val_ov = call {i8, i1} @llvm.ssub.with.overflow(i8 %x, i8 100)220 %val = extractvalue {i8, i1} %val_ov, 0221 store i8 %val, ptr %px222 %ov = extractvalue {i8, i1} %val_ov, 1223 br i1 %ov, label %trap, label %no_overflow224 225no_overflow:226 %c1 = icmp slt i8 %x, -27227 store i1 %c1, ptr %pc228 %c2 = icmp slt i8 %x, -28229 ret i1 %c2230 231trap:232 call void @llvm.trap()233 unreachable234}235 236define i1 @ssub_ov_true(i8 %x, ptr %px, ptr %pc) {237; CHECK-LABEL: @ssub_ov_true(238; CHECK-NEXT: [[VAL_OV:%.*]] = call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[X:%.*]], i8 100)239; CHECK-NEXT: [[VAL:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 0240; CHECK-NEXT: store i8 [[VAL]], ptr [[PX:%.*]], align 1241; CHECK-NEXT: [[OV:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 1242; CHECK-NEXT: br i1 [[OV]], label [[OVERFLOW:%.*]], label [[TRAP:%.*]]243; CHECK: overflow:244; CHECK-NEXT: [[C1:%.*]] = icmp samesign ult i8 [[X]], -29245; CHECK-NEXT: store i1 [[C1]], ptr [[PC:%.*]], align 1246; CHECK-NEXT: ret i1 true247; CHECK: trap:248; CHECK-NEXT: call void @llvm.trap()249; CHECK-NEXT: unreachable250;251 %val_ov = call {i8, i1} @llvm.ssub.with.overflow(i8 %x, i8 100)252 %val = extractvalue {i8, i1} %val_ov, 0253 store i8 %val, ptr %px254 %ov = extractvalue {i8, i1} %val_ov, 1255 br i1 %ov, label %overflow, label %trap256 257overflow:258 %c1 = icmp slt i8 %x, -29259 store i1 %c1, ptr %pc260 %c2 = icmp slt i8 %x, -28261 ret i1 %c2262 263trap:264 call void @llvm.trap()265 unreachable266}267 268define i1 @umul_ov_false(i8 %x, ptr %px, ptr %pc) {269; CHECK-LABEL: @umul_ov_false(270; CHECK-NEXT: [[VAL_OV:%.*]] = call { i8, i1 } @llvm.umul.with.overflow.i8(i8 [[X:%.*]], i8 10)271; CHECK-NEXT: [[VAL:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 0272; CHECK-NEXT: store i8 [[VAL]], ptr [[PX:%.*]], align 1273; CHECK-NEXT: [[OV:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 1274; CHECK-NEXT: br i1 [[OV]], label [[TRAP:%.*]], label [[NO_OVERFLOW:%.*]]275; CHECK: no_overflow:276; CHECK-NEXT: [[C1:%.*]] = icmp samesign ugt i8 [[X]], 24277; CHECK-NEXT: store i1 [[C1]], ptr [[PC:%.*]], align 1278; CHECK-NEXT: ret i1 false279; CHECK: trap:280; CHECK-NEXT: call void @llvm.trap()281; CHECK-NEXT: unreachable282;283 %val_ov = call {i8, i1} @llvm.umul.with.overflow(i8 %x, i8 10)284 %val = extractvalue {i8, i1} %val_ov, 0285 store i8 %val, ptr %px286 %ov = extractvalue {i8, i1} %val_ov, 1287 br i1 %ov, label %trap, label %no_overflow288 289no_overflow:290 %c1 = icmp ugt i8 %x, 24291 store i1 %c1, ptr %pc292 %c2 = icmp ugt i8 %x, 25293 ret i1 %c2294 295trap:296 call void @llvm.trap()297 unreachable298}299 300define i1 @umul_ov_true(i8 %x, ptr %px, ptr %pc) {301; CHECK-LABEL: @umul_ov_true(302; CHECK-NEXT: [[VAL_OV:%.*]] = call { i8, i1 } @llvm.umul.with.overflow.i8(i8 [[X:%.*]], i8 10)303; CHECK-NEXT: [[VAL:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 0304; CHECK-NEXT: store i8 [[VAL]], ptr [[PX:%.*]], align 1305; CHECK-NEXT: [[OV:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 1306; CHECK-NEXT: br i1 [[OV]], label [[OVERFLOW:%.*]], label [[TRAP:%.*]]307; CHECK: overflow:308; CHECK-NEXT: [[C1:%.*]] = icmp ugt i8 [[X]], 26309; CHECK-NEXT: store i1 [[C1]], ptr [[PC:%.*]], align 1310; CHECK-NEXT: ret i1 true311; CHECK: trap:312; CHECK-NEXT: call void @llvm.trap()313; CHECK-NEXT: unreachable314;315 %val_ov = call {i8, i1} @llvm.umul.with.overflow(i8 %x, i8 10)316 %val = extractvalue {i8, i1} %val_ov, 0317 store i8 %val, ptr %px318 %ov = extractvalue {i8, i1} %val_ov, 1319 br i1 %ov, label %overflow, label %trap320 321overflow:322 %c1 = icmp ugt i8 %x, 26323 store i1 %c1, ptr %pc324 %c2 = icmp ugt i8 %x, 25325 ret i1 %c2326 327trap:328 call void @llvm.trap()329 unreachable330}331 332; Signed mul is constrained from both sides.333define i1 @smul_ov_false_bound1(i8 %x, ptr %px, ptr %pc) {334; CHECK-LABEL: @smul_ov_false_bound1(335; CHECK-NEXT: [[VAL_OV:%.*]] = call { i8, i1 } @llvm.smul.with.overflow.i8(i8 [[X:%.*]], i8 10)336; CHECK-NEXT: [[VAL:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 0337; CHECK-NEXT: store i8 [[VAL]], ptr [[PX:%.*]], align 1338; CHECK-NEXT: [[OV:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 1339; CHECK-NEXT: br i1 [[OV]], label [[TRAP:%.*]], label [[NO_OVERFLOW:%.*]]340; CHECK: no_overflow:341; CHECK-NEXT: [[C1:%.*]] = icmp slt i8 [[X]], -11342; CHECK-NEXT: store i1 [[C1]], ptr [[PC:%.*]], align 1343; CHECK-NEXT: ret i1 false344; CHECK: trap:345; CHECK-NEXT: call void @llvm.trap()346; CHECK-NEXT: unreachable347;348 %val_ov = call {i8, i1} @llvm.smul.with.overflow(i8 %x, i8 10)349 %val = extractvalue {i8, i1} %val_ov, 0350 store i8 %val, ptr %px351 %ov = extractvalue {i8, i1} %val_ov, 1352 br i1 %ov, label %trap, label %no_overflow353 354no_overflow:355 %c1 = icmp slt i8 %x, -11356 store i1 %c1, ptr %pc357 %c2 = icmp slt i8 %x, -12358 ret i1 %c2359 360trap:361 call void @llvm.trap()362 unreachable363}364 365define i1 @smul_ov_false_bound2(i8 %x, ptr %px, ptr %pc) {366; CHECK-LABEL: @smul_ov_false_bound2(367; CHECK-NEXT: [[VAL_OV:%.*]] = call { i8, i1 } @llvm.smul.with.overflow.i8(i8 [[X:%.*]], i8 10)368; CHECK-NEXT: [[VAL:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 0369; CHECK-NEXT: store i8 [[VAL]], ptr [[PX:%.*]], align 1370; CHECK-NEXT: [[OV:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 1371; CHECK-NEXT: br i1 [[OV]], label [[TRAP:%.*]], label [[NO_OVERFLOW:%.*]]372; CHECK: no_overflow:373; CHECK-NEXT: [[C1:%.*]] = icmp sgt i8 [[X]], 11374; CHECK-NEXT: store i1 [[C1]], ptr [[PC:%.*]], align 1375; CHECK-NEXT: ret i1 false376; CHECK: trap:377; CHECK-NEXT: call void @llvm.trap()378; CHECK-NEXT: unreachable379;380 %val_ov = call {i8, i1} @llvm.smul.with.overflow(i8 %x, i8 10)381 %val = extractvalue {i8, i1} %val_ov, 0382 store i8 %val, ptr %px383 %ov = extractvalue {i8, i1} %val_ov, 1384 br i1 %ov, label %trap, label %no_overflow385 386no_overflow:387 %c1 = icmp sgt i8 %x, 11388 store i1 %c1, ptr %pc389 %c2 = icmp sgt i8 %x, 12390 ret i1 %c2391 392trap:393 call void @llvm.trap()394 unreachable395}396 397; Can't use slt/sgt to test for a hole in the range, check equality instead.398define i1 @smul_ov_true_bound1(i8 %x, ptr %px, ptr %pc) {399; CHECK-LABEL: @smul_ov_true_bound1(400; CHECK-NEXT: [[VAL_OV:%.*]] = call { i8, i1 } @llvm.smul.with.overflow.i8(i8 [[X:%.*]], i8 10)401; CHECK-NEXT: [[VAL:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 0402; CHECK-NEXT: store i8 [[VAL]], ptr [[PX:%.*]], align 1403; CHECK-NEXT: [[OV:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 1404; CHECK-NEXT: br i1 [[OV]], label [[OVERFLOW:%.*]], label [[TRAP:%.*]]405; CHECK: overflow:406; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[X]], -13407; CHECK-NEXT: store i1 [[C1]], ptr [[PC:%.*]], align 1408; CHECK-NEXT: ret i1 false409; CHECK: trap:410; CHECK-NEXT: call void @llvm.trap()411; CHECK-NEXT: unreachable412;413 %val_ov = call {i8, i1} @llvm.smul.with.overflow(i8 %x, i8 10)414 %val = extractvalue {i8, i1} %val_ov, 0415 store i8 %val, ptr %px416 %ov = extractvalue {i8, i1} %val_ov, 1417 br i1 %ov, label %overflow, label %trap418 419overflow:420 %c1 = icmp eq i8 %x, -13421 store i1 %c1, ptr %pc422 %c2 = icmp eq i8 %x, -12423 ret i1 %c2424 425trap:426 call void @llvm.trap()427 unreachable428}429 430define i1 @smul_ov_true_bound2(i8 %x, ptr %px, ptr %pc) {431; CHECK-LABEL: @smul_ov_true_bound2(432; CHECK-NEXT: [[VAL_OV:%.*]] = call { i8, i1 } @llvm.smul.with.overflow.i8(i8 [[X:%.*]], i8 10)433; CHECK-NEXT: [[VAL:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 0434; CHECK-NEXT: store i8 [[VAL]], ptr [[PX:%.*]], align 1435; CHECK-NEXT: [[OV:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 1436; CHECK-NEXT: br i1 [[OV]], label [[OVERFLOW:%.*]], label [[TRAP:%.*]]437; CHECK: overflow:438; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[X]], 13439; CHECK-NEXT: store i1 [[C1]], ptr [[PC:%.*]], align 1440; CHECK-NEXT: ret i1 false441; CHECK: trap:442; CHECK-NEXT: call void @llvm.trap()443; CHECK-NEXT: unreachable444;445 %val_ov = call {i8, i1} @llvm.smul.with.overflow(i8 %x, i8 10)446 %val = extractvalue {i8, i1} %val_ov, 0447 store i8 %val, ptr %px448 %ov = extractvalue {i8, i1} %val_ov, 1449 br i1 %ov, label %overflow, label %trap450 451overflow:452 %c1 = icmp eq i8 %x, 13453 store i1 %c1, ptr %pc454 %c2 = icmp eq i8 %x, 12455 ret i1 %c2456 457trap:458 call void @llvm.trap()459 unreachable460}461 462define i1 @uadd_val(i8 %x, ptr %pc) {463; CHECK-LABEL: @uadd_val(464; CHECK-NEXT: [[VAL_OV:%.*]] = call { i8, i1 } @llvm.uadd.with.overflow.i8(i8 [[X:%.*]], i8 100)465; CHECK-NEXT: [[OV:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 1466; CHECK-NEXT: br i1 [[OV]], label [[TRAP:%.*]], label [[NO_OVERFLOW:%.*]]467; CHECK: no_overflow:468; CHECK-NEXT: [[VAL:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 0469; CHECK-NEXT: [[C1:%.*]] = icmp ugt i8 [[VAL]], 100470; CHECK-NEXT: store i1 [[C1]], ptr [[PC:%.*]], align 1471; CHECK-NEXT: ret i1 true472; CHECK: trap:473; CHECK-NEXT: call void @llvm.trap()474; CHECK-NEXT: unreachable475;476 %val_ov = call {i8, i1} @llvm.uadd.with.overflow(i8 %x, i8 100)477 %ov = extractvalue {i8, i1} %val_ov, 1478 br i1 %ov, label %trap, label %no_overflow479 480no_overflow:481 %val = extractvalue {i8, i1} %val_ov, 0482 %c1 = icmp ugt i8 %val, 100483 store i1 %c1, ptr %pc484 %c2 = icmp uge i8 %val, 100485 ret i1 %c2486 487trap:488 call void @llvm.trap()489 unreachable490}491 492define i1 @sadd_val(i8 %x, ptr %pc) {493; CHECK-LABEL: @sadd_val(494; CHECK-NEXT: [[VAL_OV:%.*]] = call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[X:%.*]], i8 100)495; CHECK-NEXT: [[OV:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 1496; CHECK-NEXT: br i1 [[OV]], label [[TRAP:%.*]], label [[NO_OVERFLOW:%.*]]497; CHECK: no_overflow:498; CHECK-NEXT: [[VAL:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 0499; CHECK-NEXT: [[C1:%.*]] = icmp sgt i8 [[VAL]], -28500; CHECK-NEXT: store i1 [[C1]], ptr [[PC:%.*]], align 1501; CHECK-NEXT: ret i1 true502; CHECK: trap:503; CHECK-NEXT: call void @llvm.trap()504; CHECK-NEXT: unreachable505;506 %val_ov = call {i8, i1} @llvm.sadd.with.overflow(i8 %x, i8 100)507 %ov = extractvalue {i8, i1} %val_ov, 1508 br i1 %ov, label %trap, label %no_overflow509 510no_overflow:511 %val = extractvalue {i8, i1} %val_ov, 0512 %c1 = icmp sgt i8 %val, -28513 store i1 %c1, ptr %pc514 %c2 = icmp sge i8 %val, -28515 ret i1 %c2516 517trap:518 call void @llvm.trap()519 unreachable520}521 522define i1 @usub_val(i8 %x, ptr %pc) {523; CHECK-LABEL: @usub_val(524; CHECK-NEXT: [[VAL_OV:%.*]] = call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[X:%.*]], i8 100)525; CHECK-NEXT: [[OV:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 1526; CHECK-NEXT: br i1 [[OV]], label [[TRAP:%.*]], label [[NO_OVERFLOW:%.*]]527; CHECK: no_overflow:528; CHECK-NEXT: [[VAL:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 0529; CHECK-NEXT: [[C1:%.*]] = icmp ult i8 [[VAL]], -101530; CHECK-NEXT: store i1 [[C1]], ptr [[PC:%.*]], align 1531; CHECK-NEXT: ret i1 true532; CHECK: trap:533; CHECK-NEXT: call void @llvm.trap()534; CHECK-NEXT: unreachable535;536 %val_ov = call {i8, i1} @llvm.usub.with.overflow(i8 %x, i8 100)537 %ov = extractvalue {i8, i1} %val_ov, 1538 br i1 %ov, label %trap, label %no_overflow539 540no_overflow:541 %val = extractvalue {i8, i1} %val_ov, 0542 %c1 = icmp ult i8 %val, 155543 store i1 %c1, ptr %pc544 %c2 = icmp ule i8 %val, 155545 ret i1 %c2546 547trap:548 call void @llvm.trap()549 unreachable550}551 552define i1 @ssub_val(i8 %x, ptr %pc) {553; CHECK-LABEL: @ssub_val(554; CHECK-NEXT: [[VAL_OV:%.*]] = call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[X:%.*]], i8 100)555; CHECK-NEXT: [[OV:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 1556; CHECK-NEXT: br i1 [[OV]], label [[TRAP:%.*]], label [[NO_OVERFLOW:%.*]]557; CHECK: no_overflow:558; CHECK-NEXT: [[VAL:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 0559; CHECK-NEXT: [[C1:%.*]] = icmp slt i8 [[VAL]], 27560; CHECK-NEXT: store i1 [[C1]], ptr [[PC:%.*]], align 1561; CHECK-NEXT: ret i1 true562; CHECK: trap:563; CHECK-NEXT: call void @llvm.trap()564; CHECK-NEXT: unreachable565;566 %val_ov = call {i8, i1} @llvm.ssub.with.overflow(i8 %x, i8 100)567 %ov = extractvalue {i8, i1} %val_ov, 1568 br i1 %ov, label %trap, label %no_overflow569 570no_overflow:571 %val = extractvalue {i8, i1} %val_ov, 0572 %c1 = icmp slt i8 %val, 27573 store i1 %c1, ptr %pc574 %c2 = icmp sle i8 %val, 27575 ret i1 %c2576 577trap:578 call void @llvm.trap()579 unreachable580}581 582define i1 @umul_val(i8 %x, ptr %pc) {583; CHECK-LABEL: @umul_val(584; CHECK-NEXT: [[VAL_OV:%.*]] = call { i8, i1 } @llvm.umul.with.overflow.i8(i8 [[X:%.*]], i8 10)585; CHECK-NEXT: [[OV:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 1586; CHECK-NEXT: br i1 [[OV]], label [[TRAP:%.*]], label [[NO_OVERFLOW:%.*]]587; CHECK: no_overflow:588; CHECK-NEXT: [[VAL:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 0589; CHECK-NEXT: [[C1:%.*]] = icmp ult i8 [[VAL]], -6590; CHECK-NEXT: store i1 [[C1]], ptr [[PC:%.*]], align 1591; CHECK-NEXT: ret i1 true592; CHECK: trap:593; CHECK-NEXT: call void @llvm.trap()594; CHECK-NEXT: unreachable595;596 %val_ov = call {i8, i1} @llvm.umul.with.overflow(i8 %x, i8 10)597 %ov = extractvalue {i8, i1} %val_ov, 1598 br i1 %ov, label %trap, label %no_overflow599 600no_overflow:601 %val = extractvalue {i8, i1} %val_ov, 0602 %c1 = icmp ult i8 %val, 250603 store i1 %c1, ptr %pc604 %c2 = icmp ule i8 %val, 250605 ret i1 %c2606 607trap:608 call void @llvm.trap()609 unreachable610}611 612define i1 @smul_val_bound1(i8 %x, ptr %pc) {613; CHECK-LABEL: @smul_val_bound1(614; CHECK-NEXT: [[VAL_OV:%.*]] = call { i8, i1 } @llvm.smul.with.overflow.i8(i8 [[X:%.*]], i8 10)615; CHECK-NEXT: [[OV:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 1616; CHECK-NEXT: br i1 [[OV]], label [[TRAP:%.*]], label [[NO_OVERFLOW:%.*]]617; CHECK: no_overflow:618; CHECK-NEXT: [[VAL:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 0619; CHECK-NEXT: [[C1:%.*]] = icmp slt i8 [[VAL]], 120620; CHECK-NEXT: store i1 [[C1]], ptr [[PC:%.*]], align 1621; CHECK-NEXT: ret i1 true622; CHECK: trap:623; CHECK-NEXT: call void @llvm.trap()624; CHECK-NEXT: unreachable625;626 %val_ov = call {i8, i1} @llvm.smul.with.overflow(i8 %x, i8 10)627 %ov = extractvalue {i8, i1} %val_ov, 1628 br i1 %ov, label %trap, label %no_overflow629 630no_overflow:631 %val = extractvalue {i8, i1} %val_ov, 0632 %c1 = icmp slt i8 %val, 120633 store i1 %c1, ptr %pc634 %c2 = icmp sle i8 %val, 120635 ret i1 %c2636 637trap:638 call void @llvm.trap()639 unreachable640}641 642define i1 @smul_val_bound2(i8 %x, ptr %pc) {643; CHECK-LABEL: @smul_val_bound2(644; CHECK-NEXT: [[VAL_OV:%.*]] = call { i8, i1 } @llvm.smul.with.overflow.i8(i8 [[X:%.*]], i8 10)645; CHECK-NEXT: [[OV:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 1646; CHECK-NEXT: br i1 [[OV]], label [[TRAP:%.*]], label [[NO_OVERFLOW:%.*]]647; CHECK: no_overflow:648; CHECK-NEXT: [[VAL:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 0649; CHECK-NEXT: [[C1:%.*]] = icmp sgt i8 [[VAL]], -120650; CHECK-NEXT: store i1 [[C1]], ptr [[PC:%.*]], align 1651; CHECK-NEXT: ret i1 true652; CHECK: trap:653; CHECK-NEXT: call void @llvm.trap()654; CHECK-NEXT: unreachable655;656 %val_ov = call {i8, i1} @llvm.smul.with.overflow(i8 %x, i8 10)657 %ov = extractvalue {i8, i1} %val_ov, 1658 br i1 %ov, label %trap, label %no_overflow659 660no_overflow:661 %val = extractvalue {i8, i1} %val_ov, 0662 %c1 = icmp sgt i8 %val, -120663 store i1 %c1, ptr %pc664 %c2 = icmp sge i8 %val, -120665 ret i1 %c2666 667trap:668 call void @llvm.trap()669 unreachable670}671