497 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s3 4define void @test.not.uge.ult(i8 %start, i8 %low, i8 %high) {5; CHECK-LABEL: @test.not.uge.ult(6; CHECK-NEXT: entry:7; CHECK-NEXT: [[SUB_PTR_I:%.*]] = sub nuw i8 [[START:%.*]], 38; CHECK-NEXT: [[C_1:%.*]] = icmp uge i8 [[SUB_PTR_I]], [[HIGH:%.*]]9; CHECK-NEXT: br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]10; CHECK: if.then:11; CHECK-NEXT: ret void12; CHECK: if.end:13; CHECK-NEXT: [[T_0:%.*]] = icmp ult i8 [[START]], [[HIGH]]14; CHECK-NEXT: call void @use(i1 [[T_0]])15; CHECK-NEXT: [[START_1:%.*]] = sub nuw i8 [[START]], 116; CHECK-NEXT: [[T_1:%.*]] = icmp ult i8 [[START_1]], [[HIGH]]17; CHECK-NEXT: call void @use(i1 [[T_1]])18; CHECK-NEXT: [[START_2:%.*]] = sub nuw i8 [[START]], 219; CHECK-NEXT: [[T_2:%.*]] = icmp ult i8 [[START_2]], [[HIGH]]20; CHECK-NEXT: call void @use(i1 [[T_2]])21; CHECK-NEXT: [[START_3:%.*]] = sub nuw i8 [[START]], 322; CHECK-NEXT: call void @use(i1 true)23; CHECK-NEXT: [[START_4:%.*]] = sub nuw i8 [[START]], 424; CHECK-NEXT: call void @use(i1 true)25; CHECK-NEXT: ret void26;27entry:28 %sub.ptr.i = sub nuw i8 %start, 329 %c.1 = icmp uge i8 %sub.ptr.i, %high30 br i1 %c.1, label %if.then, label %if.end31 32if.then: ; preds = %entry33 ret void34 35if.end: ; preds = %entry36 %t.0 = icmp ult i8 %start, %high37 call void @use(i1 %t.0)38 %start.1 = sub nuw i8 %start, 139 %t.1 = icmp ult i8 %start.1, %high40 call void @use(i1 %t.1)41 %start.2 = sub nuw i8 %start, 242 %t.2 = icmp ult i8 %start.2, %high43 call void @use(i1 %t.2)44 %start.3 = sub nuw i8 %start, 345 %t.3 = icmp ult i8 %start.3, %high46 call void @use(i1 %t.3)47 %start.4 = sub nuw i8 %start, 448 %c.4 = icmp ult i8 %start.4, %high49 call void @use(i1 %c.4)50 ret void51}52 53define void @test.not.uge.ule(i8 %start, i8 %low, i8 %high) {54; CHECK-LABEL: @test.not.uge.ule(55; CHECK-NEXT: entry:56; CHECK-NEXT: [[SUB_PTR_I:%.*]] = sub nuw i8 [[START:%.*]], 357; CHECK-NEXT: [[C_1:%.*]] = icmp uge i8 [[SUB_PTR_I]], [[HIGH:%.*]]58; CHECK-NEXT: br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]59; CHECK: if.then:60; CHECK-NEXT: ret void61; CHECK: if.end:62; CHECK-NEXT: [[T_0:%.*]] = icmp ule i8 [[START]], [[HIGH]]63; CHECK-NEXT: call void @use(i1 [[T_0]])64; CHECK-NEXT: [[START_1:%.*]] = sub nuw i8 [[START]], 165; CHECK-NEXT: [[T_1:%.*]] = icmp ule i8 [[START_1]], [[HIGH]]66; CHECK-NEXT: call void @use(i1 [[T_1]])67; CHECK-NEXT: [[START_2:%.*]] = sub nuw i8 [[START]], 268; CHECK-NEXT: call void @use(i1 true)69; CHECK-NEXT: [[START_3:%.*]] = sub nuw i8 [[START]], 370; CHECK-NEXT: call void @use(i1 true)71; CHECK-NEXT: [[START_4:%.*]] = sub nuw i8 [[START]], 472; CHECK-NEXT: call void @use(i1 true)73; CHECK-NEXT: [[START_5:%.*]] = sub nuw i8 [[START]], 574; CHECK-NEXT: call void @use(i1 true)75; CHECK-NEXT: ret void76;77entry:78 %sub.ptr.i = sub nuw i8 %start, 379 %c.1 = icmp uge i8 %sub.ptr.i, %high80 br i1 %c.1, label %if.then, label %if.end81 82if.then: ; preds = %entry83 ret void84 85if.end: ; preds = %entry86 %t.0 = icmp ule i8 %start, %high87 call void @use(i1 %t.0)88 %start.1 = sub nuw i8 %start, 189 %t.1 = icmp ule i8 %start.1, %high90 call void @use(i1 %t.1)91 %start.2 = sub nuw i8 %start, 292 %t.2 = icmp ule i8 %start.2, %high93 call void @use(i1 %t.2)94 %start.3 = sub nuw i8 %start, 395 %t.3 = icmp ule i8 %start.3, %high96 call void @use(i1 %t.3)97 %start.4 = sub nuw i8 %start, 498 %t.4 = icmp ule i8 %start.4, %high99 call void @use(i1 %t.4)100 101 %start.5 = sub nuw i8 %start, 5102 %c.5 = icmp ule i8 %start.5, %high103 call void @use(i1 %c.5)104 105 ret void106}107 108define void @test.not.uge.ugt(i8 %start, i8 %low, i8 %high) {109; CHECK-LABEL: @test.not.uge.ugt(110; CHECK-NEXT: entry:111; CHECK-NEXT: [[SUB_PTR_I:%.*]] = sub nuw i8 [[START:%.*]], 3112; CHECK-NEXT: [[C_1:%.*]] = icmp uge i8 [[SUB_PTR_I]], [[HIGH:%.*]]113; CHECK-NEXT: br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]114; CHECK: if.then:115; CHECK-NEXT: ret void116; CHECK: if.end:117; CHECK-NEXT: [[F_0:%.*]] = icmp ugt i8 [[START]], [[HIGH]]118; CHECK-NEXT: call void @use(i1 [[F_0]])119; CHECK-NEXT: [[START_1:%.*]] = sub nuw i8 [[START]], 1120; CHECK-NEXT: [[F_1:%.*]] = icmp ugt i8 [[START_1]], [[HIGH]]121; CHECK-NEXT: call void @use(i1 [[F_1]])122; CHECK-NEXT: [[START_2:%.*]] = sub nuw i8 [[START]], 2123; CHECK-NEXT: call void @use(i1 false)124; CHECK-NEXT: [[START_3:%.*]] = sub nuw i8 [[START]], 3125; CHECK-NEXT: call void @use(i1 false)126; CHECK-NEXT: [[START_4:%.*]] = sub nuw i8 [[START]], 4127; CHECK-NEXT: call void @use(i1 false)128; CHECK-NEXT: [[START_5:%.*]] = sub nuw i8 [[START]], 5129; CHECK-NEXT: call void @use(i1 false)130; CHECK-NEXT: ret void131;132entry:133 %sub.ptr.i = sub nuw i8 %start, 3134 %c.1 = icmp uge i8 %sub.ptr.i, %high135 br i1 %c.1, label %if.then, label %if.end136 137if.then: ; preds = %entry138 ret void139 140if.end: ; preds = %entry141 %f.0 = icmp ugt i8 %start, %high142 call void @use(i1 %f.0)143 144 %start.1 = sub nuw i8 %start, 1145 %f.1 = icmp ugt i8 %start.1, %high146 call void @use(i1 %f.1)147 148 %start.2 = sub nuw i8 %start, 2149 %f.2 = icmp ugt i8 %start.2, %high150 call void @use(i1 %f.2)151 152 %start.3 = sub nuw i8 %start, 3153 %f.3 = icmp ugt i8 %start.3, %high154 call void @use(i1 %f.3)155 156 %start.4 = sub nuw i8 %start, 4157 %f.4 = icmp ugt i8 %start.4, %high158 call void @use(i1 %f.4)159 160 %start.5 = sub nuw i8 %start, 5161 %c.5 = icmp ugt i8 %start.5, %high162 call void @use(i1 %c.5)163 164 ret void165}166 167define void @test.not.uge.uge(i8 %start, i8 %low, i8 %high) {168; CHECK-LABEL: @test.not.uge.uge(169; CHECK-NEXT: entry:170; CHECK-NEXT: [[SUB_PTR_I:%.*]] = sub nuw i8 [[START:%.*]], 3171; CHECK-NEXT: [[C_1:%.*]] = icmp uge i8 [[SUB_PTR_I]], [[HIGH:%.*]]172; CHECK-NEXT: br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]173; CHECK: if.then:174; CHECK-NEXT: ret void175; CHECK: if.end:176; CHECK-NEXT: [[F_0:%.*]] = icmp ugt i8 [[START]], [[HIGH]]177; CHECK-NEXT: call void @use(i1 [[F_0]])178; CHECK-NEXT: [[START_1:%.*]] = sub nuw i8 [[START]], 1179; CHECK-NEXT: [[F_1:%.*]] = icmp uge i8 [[START_1]], [[HIGH]]180; CHECK-NEXT: call void @use(i1 [[F_1]])181; CHECK-NEXT: [[START_2:%.*]] = sub nuw i8 [[START]], 2182; CHECK-NEXT: [[F_2:%.*]] = icmp uge i8 [[START_2]], [[HIGH]]183; CHECK-NEXT: call void @use(i1 [[F_2]])184; CHECK-NEXT: [[START_3:%.*]] = sub nuw i8 [[START]], 3185; CHECK-NEXT: call void @use(i1 false)186; CHECK-NEXT: [[START_4:%.*]] = sub nuw i8 [[START]], 4187; CHECK-NEXT: call void @use(i1 false)188; CHECK-NEXT: [[START_5:%.*]] = sub nuw i8 [[START]], 5189; CHECK-NEXT: call void @use(i1 false)190; CHECK-NEXT: ret void191;192entry:193 %sub.ptr.i = sub nuw i8 %start, 3194 %c.1 = icmp uge i8 %sub.ptr.i, %high195 br i1 %c.1, label %if.then, label %if.end196 197if.then: ; preds = %entry198 ret void199 200if.end: ; preds = %entry201 %f.0 = icmp ugt i8 %start, %high202 call void @use(i1 %f.0)203 204 %start.1 = sub nuw i8 %start, 1205 %f.1 = icmp uge i8 %start.1, %high206 call void @use(i1 %f.1)207 208 %start.2 = sub nuw i8 %start, 2209 %f.2 = icmp uge i8 %start.2, %high210 call void @use(i1 %f.2)211 212 %start.3 = sub nuw i8 %start, 3213 %f.3 = icmp uge i8 %start.3, %high214 call void @use(i1 %f.3)215 216 %start.4 = sub nuw i8 %start, 4217 %c.4 = icmp uge i8 %start.4, %high218 call void @use(i1 %c.4)219 220 %start.5 = sub nuw i8 %start, 5221 %c.5 = icmp uge i8 %start.5, %high222 call void @use(i1 %c.5)223 224 ret void225}226 227define i16 @test_pr53123_sub_constraint_sign(i16 %v) {228; CHECK-LABEL: @test_pr53123_sub_constraint_sign(229; CHECK-NEXT: bb.0:230; CHECK-NEXT: [[SUB:%.*]] = sub nuw nsw i16 32767, [[V:%.*]]231; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i16 [[V]], [[SUB]]232; CHECK-NEXT: br i1 [[CMP1]], label [[BB_2:%.*]], label [[BB_1:%.*]]233; CHECK: bb.1:234; CHECK-NEXT: [[ADD:%.*]] = shl nuw nsw i16 [[V]], 1235; CHECK-NEXT: [[SUB9:%.*]] = sub nuw nsw i16 32767, [[ADD]]236; CHECK-NEXT: [[CMP11:%.*]] = icmp ugt i16 [[ADD]], [[SUB9]]237; CHECK-NEXT: br i1 [[CMP11]], label [[BB_3:%.*]], label [[BB_2]]238; CHECK: bb.2:239; CHECK-NEXT: ret i16 1240; CHECK: bb.3:241; CHECK-NEXT: ret i16 0242;243bb.0:244 %sub = sub nuw nsw i16 32767, %v245 %cmp1 = icmp ugt i16 %v, %sub246 br i1 %cmp1, label %bb.2, label %bb.1247 248bb.1:249 %add = shl nuw nsw i16 %v, 1250 %sub9 = sub nuw nsw i16 32767, %add251 %cmp11 = icmp ugt i16 %add, %sub9252 br i1 %cmp11, label %bb.3, label %bb.2253 254bb.2:255 ret i16 1256 257bb.3:258 ret i16 0259}260 261declare void @use(i1)262 263define i1 @sub_nuw_i16_simp(i16 %a) {264; CHECK-LABEL: @sub_nuw_i16_simp(265; CHECK-NEXT: entry:266; CHECK-NEXT: [[NEG2:%.*]] = sub nuw i16 [[A:%.*]], 305267; CHECK-NEXT: [[C_1:%.*]] = icmp ugt i16 0, [[NEG2]]268; CHECK-NEXT: br i1 [[C_1]], label [[EXIT_1:%.*]], label [[EXIT_2:%.*]]269; CHECK: exit.1:270; CHECK-NEXT: [[C_2:%.*]] = icmp ugt i16 [[A]], 0271; CHECK-NEXT: ret i1 [[C_2]]272; CHECK: exit.2:273; CHECK-NEXT: ret i1 true274;275entry:276 %neg2 = sub nuw i16 %a, 305277 %c.1 = icmp ugt i16 0, %neg2278 br i1 %c.1, label %exit.1, label %exit.2279 280exit.1:281 %c.2 = icmp ugt i16 %a, 0282 ret i1 %c.2283 284exit.2:285 %c.3 = icmp ugt i16 %a, 0286 ret i1 %c.3287}288 289define i1 @sub_nuw_i64_simp(i64 %a) {290; CHECK-LABEL: @sub_nuw_i64_simp(291; CHECK-NEXT: entry:292; CHECK-NEXT: [[NEG2:%.*]] = sub nuw i64 [[A:%.*]], 305293; CHECK-NEXT: [[C_1:%.*]] = icmp ugt i64 0, [[NEG2]]294; CHECK-NEXT: br i1 [[C_1]], label [[EXIT_1:%.*]], label [[EXIT_2:%.*]]295; CHECK: exit.1:296; CHECK-NEXT: [[C_2:%.*]] = icmp ugt i64 [[A]], 0297; CHECK-NEXT: ret i1 [[C_2]]298; CHECK: exit.2:299; CHECK-NEXT: ret i1 true300;301entry:302 %neg2 = sub nuw i64 %a, 305303 %c.1 = icmp ugt i64 0, %neg2304 br i1 %c.1, label %exit.1, label %exit.2305 306exit.1:307 %c.2 = icmp ugt i64 %a, 0308 ret i1 %c.2309 310exit.2:311 %c.3 = icmp ugt i64 %a, 0312 ret i1 %c.3313}314 315define i1 @sub_nuw_neg_i16(i16 %a) {316; CHECK-LABEL: @sub_nuw_neg_i16(317; CHECK-NEXT: entry:318; CHECK-NEXT: [[NEG2:%.*]] = sub nuw i16 [[A:%.*]], -305319; CHECK-NEXT: [[C_1:%.*]] = icmp ugt i16 0, [[NEG2]]320; CHECK-NEXT: br i1 [[C_1]], label [[EXIT_1:%.*]], label [[EXIT_2:%.*]]321; CHECK: exit.1:322; CHECK-NEXT: [[C_2:%.*]] = icmp ugt i16 [[A]], 0323; CHECK-NEXT: ret i1 [[C_2]]324; CHECK: exit.2:325; CHECK-NEXT: ret i1 true326;327entry:328 %neg2 = sub nuw i16 %a, -305329 %c.1 = icmp ugt i16 0, %neg2330 br i1 %c.1, label %exit.1, label %exit.2331 332exit.1:333 %c.2 = icmp ugt i16 %a, 0334 ret i1 %c.2335 336exit.2:337 %c.3 = icmp ugt i16 %a, 0338 ret i1 %c.3339}340 341declare void @llvm.assume(i1)342 343define i1 @wrapping_offset_sum(i64 %x) {344; CHECK-LABEL: @wrapping_offset_sum(345; CHECK-NEXT: [[NON_ZERO:%.*]] = icmp ugt i64 [[X:%.*]], 0346; CHECK-NEXT: call void @llvm.assume(i1 [[NON_ZERO]])347; CHECK-NEXT: [[ADD:%.*]] = sub nuw i64 [[X]], 9223372036854775802348; CHECK-NEXT: [[ULT:%.*]] = icmp ugt i64 200, [[ADD]]349; CHECK-NEXT: ret i1 [[ULT]]350;351 %non.zero = icmp ugt i64 %x, 0352 call void @llvm.assume(i1 %non.zero)353 %add = sub nuw i64 %x, 9223372036854775802354 %ult = icmp ugt i64 200, %add355 ret i1 %ult356}357 358define i1 @sub_nuw_i64_signed_min(i64 %a) {359; CHECK-LABEL: @sub_nuw_i64_signed_min(360; CHECK-NEXT: entry:361; CHECK-NEXT: [[SUB:%.*]] = sub nuw i64 [[A:%.*]], -9223372036854775808362; CHECK-NEXT: [[C_1:%.*]] = icmp ugt i64 [[A]], [[SUB]]363; CHECK-NEXT: ret i1 [[C_1]]364;365entry:366 %sub = sub nuw i64 %a, -9223372036854775808367 %c.1 = icmp ugt i64 %a, %sub368 ret i1 %c.1369}370 371define i1 @sub_nuw_i64_signed_min_const(i64 %a) {372; CHECK-LABEL: @sub_nuw_i64_signed_min_const(373; CHECK-NEXT: entry:374; CHECK-NEXT: [[NEG2:%.*]] = sub nuw i64 0, -9223372036854775808375; CHECK-NEXT: [[C:%.*]] = icmp ugt i64 [[NEG2]], 0376; CHECK-NEXT: ret i1 [[C]]377;378entry:379 %neg2 = sub nuw i64 0, -9223372036854775808380 %c = icmp ugt i64 %neg2, 0381 ret i1 %c382}383 384define i1 @pr76713(i16 %i1, i16 %i3) {385; CHECK-LABEL: @pr76713(386; CHECK-NEXT: entry:387; CHECK-NEXT: [[C1:%.*]] = icmp ult i16 [[I1:%.*]], -1388; CHECK-NEXT: [[C2:%.*]] = icmp uge i16 [[I1]], -3389; CHECK-NEXT: [[C3:%.*]] = icmp ult i16 [[I3:%.*]], 2390; CHECK-NEXT: [[AND:%.*]] = and i1 [[C1]], [[C2]]391; CHECK-NEXT: [[AND_2:%.*]] = and i1 [[AND]], [[C3]]392; CHECK-NEXT: br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]393; CHECK: then:394; CHECK-NEXT: [[SUB:%.*]] = sub nuw nsw i16 [[I1]], -3395; CHECK-NEXT: [[ARRAYIDX_IDX:%.*]] = mul nuw nsw i16 [[I3]], 4396; CHECK-NEXT: [[I6:%.*]] = add nuw nsw i16 [[ARRAYIDX_IDX]], [[SUB]]397; CHECK-NEXT: [[C4:%.*]] = icmp ult i16 12, [[I6]]398; CHECK-NEXT: ret i1 [[C4]]399; CHECK: else:400; CHECK-NEXT: ret i1 false401;402entry:403 %c1 = icmp ult i16 %i1, -1404 %c2 = icmp uge i16 %i1, -3405 %c3 = icmp ult i16 %i3, 2406 %and = and i1 %c1, %c2407 %and.2 = and i1 %and, %c3408 br i1 %and, label %then, label %else409 410then:411 %sub = sub nuw nsw i16 %i1, -3412 %arrayidx.idx = mul nuw nsw i16 %i3, 4413 %i6 = add nuw nsw i16 %arrayidx.idx, %sub414 %c4 = icmp ult i16 12, %i6415 ret i1 %c4416 417else:418 ret i1 0419}420 421define void @sub_nuw_chained_positive_constants(i16 %a) {422; CHECK-LABEL: @sub_nuw_chained_positive_constants(423; CHECK-NEXT: entry:424; CHECK-NEXT: [[SUB1:%.*]] = sub nuw i16 [[A:%.*]], 10425; CHECK-NEXT: [[SUB2:%.*]] = sub nuw i16 [[SUB1]], 20426; CHECK-NEXT: [[C_1:%.*]] = icmp ugt i16 [[SUB2]], 90427; CHECK-NEXT: br i1 [[C_1]], label [[EXIT_1:%.*]], label [[EXIT_2:%.*]]428; CHECK: exit.1:429; CHECK-NEXT: call void @use(i1 true)430; CHECK-NEXT: [[C_3:%.*]] = icmp ugt i16 [[A]], 121431; CHECK-NEXT: call void @use(i1 [[C_3]])432; CHECK-NEXT: ret void433; CHECK: exit.2:434; CHECK-NEXT: call void @use(i1 false)435; CHECK-NEXT: call void @use(i1 false)436; CHECK-NEXT: ret void437;438entry:439 %sub1 = sub nuw i16 %a, 10440 %sub2 = sub nuw i16 %sub1, 20441 %c.1 = icmp ugt i16 %sub2, 90442 br i1 %c.1, label %exit.1, label %exit.2443 444exit.1:445 %c.2 = icmp ugt i16 %a, 120446 call void @use(i1 %c.2)447 %c.3 = icmp ugt i16 %a, 121448 call void @use(i1 %c.3)449 ret void450 451exit.2:452 %c.4 = icmp ugt i16 %a, 120453 call void @use(i1 %c.4)454 %c.5 = icmp ugt i16 %a, 121455 call void @use(i1 %c.5)456 ret void457}458 459define void @sub_nuw_chained_negative_constants(i8 %a) {460; CHECK-LABEL: @sub_nuw_chained_negative_constants(461; CHECK-NEXT: entry:462; CHECK-NEXT: [[SUB1:%.*]] = sub nuw i8 [[A:%.*]], 10463; CHECK-NEXT: [[SUB2:%.*]] = sub nuw i8 [[SUB1]], -126464; CHECK-NEXT: [[C_1:%.*]] = icmp ugt i8 [[SUB2]], 20465; CHECK-NEXT: br i1 [[C_1]], label [[EXIT_1:%.*]], label [[EXIT_2:%.*]]466; CHECK: exit.1:467; CHECK-NEXT: call void @use(i1 true)468; CHECK-NEXT: [[C_3:%.*]] = icmp ugt i8 [[A]], -95469; CHECK-NEXT: call void @use(i1 [[C_3]])470; CHECK-NEXT: ret void471; CHECK: exit.2:472; CHECK-NEXT: call void @use(i1 false)473; CHECK-NEXT: call void @use(i1 false)474; CHECK-NEXT: ret void475;476entry:477 %sub1 = sub nuw i8 %a, 10478 %sub2 = sub nuw i8 %sub1, 130479 %c.1 = icmp ugt i8 %sub2, 20480 br i1 %c.1, label %exit.1, label %exit.2481 482exit.1:483 %c.2 = icmp ugt i8 %a, 160484 call void @use(i1 %c.2)485 %c.3 = icmp ugt i8 %a, 161486 call void @use(i1 %c.3)487 ret void488 489 490exit.2:491 %c.4 = icmp ugt i8 %a, 160492 call void @use(i1 %c.4)493 %c.5 = icmp ugt i8 %a, 161494 call void @use(i1 %c.5)495 ret void496}497