2099 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 22; RUN: opt < %s -passes=correlated-propagation -S | FileCheck %s3; PR25814 5define i32 @test1(i1 %C) {6; CHECK-LABEL: define range(i32 10, 12) i32 @test17; CHECK-SAME: (i1 [[C:%.*]]) {8; CHECK-NEXT: br i1 [[C]], label [[EXIT:%.*]], label [[BODY:%.*]]9; CHECK: body:10; CHECK-NEXT: ret i32 1111; CHECK: exit:12; CHECK-NEXT: ret i32 1013;14 br i1 %C, label %exit, label %body15 16body: ; preds = %017 %A = select i1 %C, i32 10, i32 1118 ret i32 %A19 20exit: ; preds = %021 ret i32 1022}23 24; PR442025declare i1 @ext()26define i1 @test2() {27; CHECK-LABEL: define i1 @test2() {28; CHECK-NEXT: entry:29; CHECK-NEXT: [[COND:%.*]] = tail call i1 @ext()30; CHECK-NEXT: br i1 [[COND]], label [[BB1:%.*]], label [[BB2:%.*]]31; CHECK: bb1:32; CHECK-NEXT: [[COND2:%.*]] = tail call i1 @ext()33; CHECK-NEXT: br i1 [[COND2]], label [[BB3:%.*]], label [[BB2]]34; CHECK: bb2:35; CHECK-NEXT: ret i1 false36; CHECK: bb3:37; CHECK-NEXT: [[RES:%.*]] = tail call i1 @ext()38; CHECK-NEXT: ret i1 [[RES]]39;40entry:41 %cond = tail call i1 @ext()42 br i1 %cond, label %bb1, label %bb243 44bb1:45 %cond2 = tail call i1 @ext()46 br i1 %cond2, label %bb3, label %bb247 48bb2:49 %cond_merge = phi i1 [ %cond, %entry ], [ false, %bb1 ]50 ret i1 %cond_merge51 52bb3:53 %res = tail call i1 @ext()54 ret i1 %res55}56 57; PR485558@gv = internal constant i8 759define i8 @test3(ptr %a) nounwind {60; CHECK-LABEL: define i8 @test361; CHECK-SAME: (ptr [[A:%.*]]) #[[ATTR0:[0-9]+]] {62; CHECK-NEXT: entry:63; CHECK-NEXT: [[COND:%.*]] = icmp eq ptr [[A]], @gv64; CHECK-NEXT: br i1 [[COND]], label [[BB2:%.*]], label [[BB:%.*]]65; CHECK: bb:66; CHECK-NEXT: ret i8 067; CHECK: bb2:68; CHECK-NEXT: [[SHOULD_BE_CONST:%.*]] = load i8, ptr [[A]], align 169; CHECK-NEXT: ret i8 [[SHOULD_BE_CONST]]70;71entry:72 %cond = icmp eq ptr %a, @gv73 br i1 %cond, label %bb2, label %bb74 75bb:76 ret i8 077 78bb2:79 %should_be_const = load i8, ptr %a80 ret i8 %should_be_const81}82 83; PR175784define i32 @test4(i32) {85; CHECK-LABEL: define range(i32 0, 3) i32 @test486; CHECK-SAME: (i32 [[TMP0:%.*]]) {87; CHECK-NEXT: EntryBlock:88; CHECK-NEXT: [[DOTDEMORGAN:%.*]] = icmp sgt i32 [[TMP0]], 289; CHECK-NEXT: br i1 [[DOTDEMORGAN]], label [[GREATERTHANTWO:%.*]], label [[LESSTHANOREQUALTOTWO:%.*]]90; CHECK: GreaterThanTwo:91; CHECK-NEXT: br i1 false, label [[IMPOSSIBLE:%.*]], label [[NOTTWOANDGREATERTHANTWO:%.*]]92; CHECK: NotTwoAndGreaterThanTwo:93; CHECK-NEXT: ret i32 294; CHECK: Impossible:95; CHECK-NEXT: ret i32 196; CHECK: LessThanOrEqualToTwo:97; CHECK-NEXT: ret i32 098;99EntryBlock:100 %.demorgan = icmp sgt i32 %0, 2101 br i1 %.demorgan, label %GreaterThanTwo, label %LessThanOrEqualToTwo102 103GreaterThanTwo:104 icmp eq i32 %0, 2105 br i1 %1, label %Impossible, label %NotTwoAndGreaterThanTwo106 107NotTwoAndGreaterThanTwo:108 ret i32 2109 110Impossible:111 ret i32 1112 113LessThanOrEqualToTwo:114 ret i32 0115}116 117declare ptr @f(ptr)118define void @test5(ptr %x, ptr %y) {119; CHECK-LABEL: define void @test5120; CHECK-SAME: (ptr [[X:%.*]], ptr [[Y:%.*]]) {121; CHECK-NEXT: entry:122; CHECK-NEXT: [[PRE:%.*]] = icmp eq ptr [[X]], null123; CHECK-NEXT: br i1 [[PRE]], label [[RETURN:%.*]], label [[LOOP:%.*]]124; CHECK: loop:125; CHECK-NEXT: [[PHI:%.*]] = phi ptr [ [[F:%.*]], [[LOOP]] ], [ [[X]], [[ENTRY:%.*]] ]126; CHECK-NEXT: [[F]] = tail call ptr @f(ptr [[PHI]])127; CHECK-NEXT: [[CMP1:%.*]] = icmp ne ptr [[F]], [[Y]]128; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], ptr [[F]], ptr null129; CHECK-NEXT: [[CMP2:%.*]] = icmp eq ptr [[SEL]], null130; CHECK-NEXT: br i1 [[CMP2]], label [[RETURN]], label [[LOOP]]131; CHECK: return:132; CHECK-NEXT: ret void133;134entry:135 %pre = icmp eq ptr %x, null136 br i1 %pre, label %return, label %loop137 138loop:139 %phi = phi ptr [ %sel, %loop ], [ %x, %entry ]140 %f = tail call ptr @f(ptr %phi)141 %cmp1 = icmp ne ptr %f, %y142 %sel = select i1 %cmp1, ptr %f, ptr null143 %cmp2 = icmp eq ptr %sel, null144 br i1 %cmp2, label %return, label %loop145 146return:147 ret void148}149 150; "false" case for CorrelatedValuePropagation151define void @loop1(ptr %x, ptr %y) {152; CHECK-LABEL: define void @loop1153; CHECK-SAME: (ptr [[X:%.*]], ptr [[Y:%.*]]) {154; CHECK-NEXT: entry:155; CHECK-NEXT: br label [[LOOP:%.*]]156; CHECK: loop:157; CHECK-NEXT: [[PHI:%.*]] = phi ptr [ [[F:%.*]], [[LOOP]] ], [ [[X]], [[ENTRY:%.*]] ]158; CHECK-NEXT: [[F]] = tail call ptr @f(ptr [[PHI]])159; CHECK-NEXT: [[CMP1:%.*]] = icmp ne ptr [[F]], [[Y]]160; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], ptr [[F]], ptr null161; CHECK-NEXT: [[CMP2:%.*]] = icmp eq ptr [[SEL]], null162; CHECK-NEXT: br i1 [[CMP2]], label [[RETURN:%.*]], label [[LOOP]]163; CHECK: return:164; CHECK-NEXT: ret void165;166entry:167 br label %loop168 169loop:170 %phi = phi ptr [ %sel, %loop ], [ %x, %entry ]171 %f = tail call ptr @f(ptr %phi)172 %cmp1 = icmp ne ptr %f, %y173 %sel = select i1 %cmp1, ptr %f, ptr null174 %cmp2 = icmp eq ptr %sel, null175 br i1 %cmp2, label %return, label %loop176 177return:178 ret void179}180 181; "true" case for CorrelatedValuePropagation182define void @loop2(ptr %x, ptr %y) {183; CHECK-LABEL: define void @loop2184; CHECK-SAME: (ptr [[X:%.*]], ptr [[Y:%.*]]) {185; CHECK-NEXT: entry:186; CHECK-NEXT: br label [[LOOP:%.*]]187; CHECK: loop:188; CHECK-NEXT: [[PHI:%.*]] = phi ptr [ [[F:%.*]], [[LOOP]] ], [ [[X]], [[ENTRY:%.*]] ]189; CHECK-NEXT: [[F]] = tail call ptr @f(ptr [[PHI]])190; CHECK-NEXT: [[CMP1:%.*]] = icmp eq ptr [[F]], [[Y]]191; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], ptr null, ptr [[F]]192; CHECK-NEXT: [[CMP2:%.*]] = icmp eq ptr [[SEL]], null193; CHECK-NEXT: br i1 [[CMP2]], label [[RETURN:%.*]], label [[LOOP]]194; CHECK: return:195; CHECK-NEXT: ret void196;197entry:198 br label %loop199 200loop:201 %phi = phi ptr [ %sel, %loop ], [ %x, %entry ]202 %f = tail call ptr @f(ptr %phi)203 %cmp1 = icmp eq ptr %f, %y204 %sel = select i1 %cmp1, ptr null, ptr %f205 %cmp2 = icmp eq ptr %sel, null206 br i1 %cmp2, label %return, label %loop207 208return:209 ret void210}211 212define i32 @switch1(i32 %s) {213; CHECK-LABEL: define range(i32 -1, 2) i32 @switch1214; CHECK-SAME: (i32 [[S:%.*]]) {215; CHECK-NEXT: entry:216; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[S]], 0217; CHECK-NEXT: br i1 [[CMP]], label [[NEGATIVE:%.*]], label [[OUT:%.*]]218; CHECK: negative:219; CHECK-NEXT: switch i32 [[S]], label [[OUT]] [220; CHECK-NEXT: i32 -2, label [[NEXT:%.*]]221; CHECK-NEXT: i32 -1, label [[NEXT]]222; CHECK-NEXT: ]223; CHECK: out:224; CHECK-NEXT: [[P:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ -1, [[NEGATIVE]] ]225; CHECK-NEXT: ret i32 [[P]]226; CHECK: next:227; CHECK-NEXT: ret i32 0228;229entry:230 %cmp = icmp slt i32 %s, 0231 br i1 %cmp, label %negative, label %out232 233negative:234 switch i32 %s, label %out [235 i32 0, label %out236 i32 1, label %out237 i32 -1, label %next238 i32 -2, label %next239 i32 2, label %out240 i32 3, label %out241 ]242 243out:244 %p = phi i32 [ 1, %entry ], [ -1, %negative ], [ -1, %negative ], [ -1, %negative ], [ -1, %negative ], [ -1, %negative ]245 ret i32 %p246 247next:248 %q = phi i32 [ 0, %negative ], [ 0, %negative ]249 ret i32 %q250}251 252define i32 @switch2(i32 %s) {253; CHECK-LABEL: define range(i32 -1, 2) i32 @switch2254; CHECK-SAME: (i32 [[S:%.*]]) {255; CHECK-NEXT: entry:256; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[S]], 0257; CHECK-NEXT: br i1 [[CMP]], label [[POSITIVE:%.*]], label [[OUT:%.*]]258; CHECK: positive:259; CHECK-NEXT: br label [[OUT]]260; CHECK: out:261; CHECK-NEXT: [[P:%.*]] = phi i32 [ -1, [[ENTRY:%.*]] ], [ 1, [[POSITIVE]] ]262; CHECK-NEXT: ret i32 [[P]]263; CHECK: next:264; CHECK-NEXT: ret i32 0265;266entry:267 %cmp = icmp sgt i32 %s, 0268 br i1 %cmp, label %positive, label %out269 270positive:271 switch i32 %s, label %out [272 i32 0, label %out273 i32 -1, label %next274 i32 -2, label %next275 ]276 277out:278 %p = phi i32 [ -1, %entry ], [ 1, %positive ], [ 1, %positive ]279 ret i32 %p280 281next:282 %q = phi i32 [ 0, %positive ], [ 0, %positive ]283 ret i32 %q284}285 286define i32 @switch3(i32 %s) {287; CHECK-LABEL: define range(i32 -1, 2) i32 @switch3288; CHECK-SAME: (i32 [[S:%.*]]) {289; CHECK-NEXT: entry:290; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[S]], 0291; CHECK-NEXT: br i1 [[CMP]], label [[POSITIVE:%.*]], label [[OUT:%.*]]292; CHECK: positive:293; CHECK-NEXT: br label [[OUT]]294; CHECK: out:295; CHECK-NEXT: [[P:%.*]] = phi i32 [ -1, [[ENTRY:%.*]] ], [ 1, [[POSITIVE]] ]296; CHECK-NEXT: ret i32 [[P]]297; CHECK: next:298; CHECK-NEXT: ret i32 0299;300entry:301 %cmp = icmp sgt i32 %s, 0302 br i1 %cmp, label %positive, label %out303 304positive:305 switch i32 %s, label %out [306 i32 -1, label %out307 i32 -2, label %next308 i32 -3, label %next309 ]310 311out:312 %p = phi i32 [ -1, %entry ], [ 1, %positive ], [ 1, %positive ]313 ret i32 %p314 315next:316 %q = phi i32 [ 0, %positive ], [ 0, %positive ]317 ret i32 %q318}319 320define void @switch4(i32 %s) {321; CHECK-LABEL: define void @switch4322; CHECK-SAME: (i32 [[S:%.*]]) {323; CHECK-NEXT: entry:324; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[S]], 0325; CHECK-NEXT: br i1 [[CMP]], label [[ZERO:%.*]], label [[OUT:%.*]]326; CHECK: zero:327; CHECK-NEXT: br label [[NEXT:%.*]]328; CHECK: out:329; CHECK-NEXT: ret void330; CHECK: next:331; CHECK-NEXT: ret void332;333entry:334 %cmp = icmp eq i32 %s, 0335 br i1 %cmp, label %zero, label %out336 337zero:338 switch i32 %s, label %out [339 i32 0, label %next340 i32 1, label %out341 i32 -1, label %out342 ]343 344out:345 ret void346 347next:348 ret void349}350 351define void @switch_nonzero_zext(i8 %s) {352; CHECK-LABEL: define void @switch_nonzero_zext353; CHECK-SAME: (i8 [[S:%.*]]) {354; CHECK-NEXT: entry:355; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[S]], 0356; CHECK-NEXT: br i1 [[CMP]], label [[SWITCH:%.*]], label [[EXIT:%.*]]357; CHECK: switch:358; CHECK-NEXT: [[S_EXT:%.*]] = zext i8 [[S]] to i32359; CHECK-NEXT: br label [[EXIT]]360; CHECK: exit:361; CHECK-NEXT: ret void362; CHECK: unreachable:363; CHECK-NEXT: ret void364;365entry:366 %cmp = icmp ne i8 %s, 0367 br i1 %cmp, label %switch, label %exit368 369switch:370 %s.ext = zext i8 %s to i32371 switch i32 %s.ext, label %exit [372 i32 0, label %unreachable373 i32 1, label %exit374 i32 -1, label %exit375 ]376 377exit:378 ret void379 380unreachable:381 ret void382}383 384define void @switch_assume_nonzero(i32 %s) {385; CHECK-LABEL: define void @switch_assume_nonzero386; CHECK-SAME: (i32 [[S:%.*]]) {387; CHECK-NEXT: entry:388; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[S]], 0389; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])390; CHECK-NEXT: br label [[EXIT:%.*]]391; CHECK: exit:392; CHECK-NEXT: ret void393; CHECK: unreachable:394; CHECK-NEXT: ret void395;396entry:397 %cmp = icmp ne i32 %s, 0398 call void @llvm.assume(i1 %cmp)399 switch i32 %s, label %exit [400 i32 0, label %unreachable401 i32 1, label %exit402 i32 -1, label %exit403 ]404 405exit:406 ret void407 408unreachable:409 ret void410}411 412define void @switch_nonzero_phi(i1 %cond) {413; CHECK-LABEL: define void @switch_nonzero_phi414; CHECK-SAME: (i1 [[COND:%.*]]) {415; CHECK-NEXT: entry:416; CHECK-NEXT: br i1 [[COND]], label [[IF:%.*]], label [[ELSE:%.*]]417; CHECK: if:418; CHECK-NEXT: br label [[SWITCH:%.*]]419; CHECK: else:420; CHECK-NEXT: br label [[SWITCH]]421; CHECK: switch:422; CHECK-NEXT: [[S:%.*]] = phi i32 [ 1, [[IF]] ], [ -1, [[ELSE]] ]423; CHECK-NEXT: br label [[EXIT:%.*]]424; CHECK: exit:425; CHECK-NEXT: ret void426; CHECK: unreachable:427; CHECK-NEXT: ret void428;429entry:430 br i1 %cond, label %if, label %else431 432if:433 br label %switch434 435else:436 br label %switch437 438switch:439 %s = phi i32 [ 1, %if ], [ -1, %else ]440 switch i32 %s, label %exit [441 i32 0, label %unreachable442 i32 1, label %exit443 i32 -1, label %exit444 ]445 446exit:447 ret void448 449unreachable:450 ret void451}452 453define i32 @switch_range(i32 %cond) {454; CHECK-LABEL: define range(i32 1, 3) i32 @switch_range455; CHECK-SAME: (i32 [[COND:%.*]]) {456; CHECK-NEXT: entry:457; CHECK-NEXT: [[S:%.*]] = urem i32 [[COND]], 3458; CHECK-NEXT: [[S1:%.*]] = add nuw nsw i32 [[S]], 1459; CHECK-NEXT: switch i32 [[S1]], label [[DEFAULT_UNREACHABLE:%.*]] [460; CHECK-NEXT: i32 1, label [[EXIT1:%.*]]461; CHECK-NEXT: i32 2, label [[EXIT2:%.*]]462; CHECK-NEXT: i32 3, label [[EXIT1]]463; CHECK-NEXT: ]464; CHECK: exit1:465; CHECK-NEXT: ret i32 1466; CHECK: exit2:467; CHECK-NEXT: ret i32 2468; CHECK: default.unreachable:469; CHECK-NEXT: unreachable470; CHECK: unreachable:471; CHECK-NEXT: ret i32 0472;473entry:474 %s = urem i32 %cond, 3475 %s1 = add i32 %s, 1476 switch i32 %s1, label %unreachable [477 i32 1, label %exit1478 i32 2, label %exit2479 i32 3, label %exit1480 ]481 482exit1:483 ret i32 1484exit2:485 ret i32 2486unreachable:487 ret i32 0488}489 490; If the cases do not cover the entire range of the491; switch condition, we should not change the default.492 493define i32 @switch_range_not_full(i32 %cond) {494; CHECK-LABEL: define range(i32 0, 3) i32 @switch_range_not_full495; CHECK-SAME: (i32 [[COND:%.*]]) {496; CHECK-NEXT: entry:497; CHECK-NEXT: [[S:%.*]] = urem i32 [[COND]], 3498; CHECK-NEXT: [[S1:%.*]] = add nuw nsw i32 [[S]], 1499; CHECK-NEXT: switch i32 [[S1]], label [[UNREACHABLE:%.*]] [500; CHECK-NEXT: i32 1, label [[EXIT1:%.*]]501; CHECK-NEXT: i32 3, label [[EXIT2:%.*]]502; CHECK-NEXT: ]503; CHECK: exit1:504; CHECK-NEXT: ret i32 1505; CHECK: exit2:506; CHECK-NEXT: ret i32 2507; CHECK: unreachable:508; CHECK-NEXT: ret i32 0509;510entry:511 %s = urem i32 %cond, 3512 %s1 = add i32 %s, 1513 switch i32 %s1, label %unreachable [514 i32 1, label %exit1515 i32 3, label %exit2516 ]517 518exit1:519 ret i32 1520exit2:521 ret i32 2522unreachable:523 ret i32 0524}525 526; PR51531527 528define i8 @switch_defaultdest_multipleuse(i8 %t0) {529; CHECK-LABEL: define i8 @switch_defaultdest_multipleuse530; CHECK-SAME: (i8 [[T0:%.*]]) {531; CHECK-NEXT: entry:532; CHECK-NEXT: [[O:%.*]] = or i8 [[T0]], 1533; CHECK-NEXT: [[R:%.*]] = srem i8 1, [[O]]534; CHECK-NEXT: br label [[EXIT:%.*]]535; CHECK: default.unreachable:536; CHECK-NEXT: unreachable537; CHECK: exit:538; CHECK-NEXT: ret i8 0539;540entry:541 %o = or i8 %t0, 1542 %r = srem i8 1, %o543 switch i8 %r, label %exit [544 i8 0, label %exit545 i8 1, label %exit546 ]547 548exit:549 ret i8 0550}551 552define i1 @arg_attribute(ptr nonnull %a) {553; CHECK-LABEL: define i1 @arg_attribute554; CHECK-SAME: (ptr nonnull [[A:%.*]]) {555; CHECK-NEXT: ret i1 false556;557 %cmp = icmp eq ptr %a, null558 ret i1 %cmp559}560 561declare nonnull ptr @return_nonnull()562define i1 @call_attribute() {563; CHECK-LABEL: define i1 @call_attribute() {564; CHECK-NEXT: [[A:%.*]] = call ptr @return_nonnull()565; CHECK-NEXT: ret i1 false566;567 %a = call ptr @return_nonnull()568 %cmp = icmp eq ptr %a, null569 ret i1 %cmp570}571 572define i1 @umin(i32 %a, i32 %b) {573; CHECK-LABEL: define i1 @umin574; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {575; CHECK-NEXT: entry:576; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A]], 5577; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]578; CHECK: a_guard:579; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[B]], 20580; CHECK-NEXT: br i1 [[CMP2]], label [[B_GUARD:%.*]], label [[OUT]]581; CHECK: b_guard:582; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp samesign ult i32 [[A]], [[B]]583; CHECK-NEXT: [[MIN:%.*]] = select i1 [[SEL_CMP]], i32 [[A]], i32 [[B]]584; CHECK-NEXT: ret i1 false585; CHECK: out:586; CHECK-NEXT: ret i1 false587;588entry:589 %cmp = icmp ult i32 %a, 5590 br i1 %cmp, label %a_guard, label %out591 592a_guard:593 %cmp2 = icmp ult i32 %b, 20594 br i1 %cmp2, label %b_guard, label %out595 596b_guard:597 %sel_cmp = icmp ult i32 %a, %b598 %min = select i1 %sel_cmp, i32 %a, i32 %b599 %res = icmp eq i32 %min, 7600 ret i1 %res601out:602 ret i1 false603}604 605define i1 @smin(i32 %a, i32 %b) {606; CHECK-LABEL: define i1 @smin607; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {608; CHECK-NEXT: entry:609; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A]], 5610; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]611; CHECK: a_guard:612; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[B]], 20613; CHECK-NEXT: br i1 [[CMP2]], label [[B_GUARD:%.*]], label [[OUT]]614; CHECK: b_guard:615; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp samesign ule i32 [[A]], [[B]]616; CHECK-NEXT: [[MIN:%.*]] = select i1 [[SEL_CMP]], i32 [[A]], i32 [[B]]617; CHECK-NEXT: ret i1 false618; CHECK: out:619; CHECK-NEXT: ret i1 false620;621entry:622 %cmp = icmp ult i32 %a, 5623 br i1 %cmp, label %a_guard, label %out624 625a_guard:626 %cmp2 = icmp ult i32 %b, 20627 br i1 %cmp2, label %b_guard, label %out628 629b_guard:630 %sel_cmp = icmp sle i32 %a, %b631 %min = select i1 %sel_cmp, i32 %a, i32 %b632 %res = icmp eq i32 %min, 7633 ret i1 %res634out:635 ret i1 false636}637 638define i1 @smax(i32 %a, i32 %b) {639; CHECK-LABEL: define i1 @smax640; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {641; CHECK-NEXT: entry:642; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A]], 5643; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]644; CHECK: a_guard:645; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[B]], 20646; CHECK-NEXT: br i1 [[CMP2]], label [[B_GUARD:%.*]], label [[OUT]]647; CHECK: b_guard:648; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp samesign uge i32 [[A]], [[B]]649; CHECK-NEXT: [[MAX:%.*]] = select i1 [[SEL_CMP]], i32 [[A]], i32 [[B]]650; CHECK-NEXT: ret i1 false651; CHECK: out:652; CHECK-NEXT: ret i1 false653;654entry:655 %cmp = icmp sgt i32 %a, 5656 br i1 %cmp, label %a_guard, label %out657 658a_guard:659 %cmp2 = icmp sgt i32 %b, 20660 br i1 %cmp2, label %b_guard, label %out661 662b_guard:663 %sel_cmp = icmp sge i32 %a, %b664 %max = select i1 %sel_cmp, i32 %a, i32 %b665 %res = icmp eq i32 %max, 7666 ret i1 %res667out:668 ret i1 false669}670 671define i1 @umax(i32 %a, i32 %b) {672; CHECK-LABEL: define i1 @umax673; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {674; CHECK-NEXT: entry:675; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A]], 5676; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]677; CHECK: a_guard:678; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[B]], 20679; CHECK-NEXT: br i1 [[CMP2]], label [[B_GUARD:%.*]], label [[OUT]]680; CHECK: b_guard:681; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp samesign uge i32 [[A]], [[B]]682; CHECK-NEXT: [[MAX:%.*]] = select i1 [[SEL_CMP]], i32 [[A]], i32 [[B]]683; CHECK-NEXT: ret i1 false684; CHECK: out:685; CHECK-NEXT: ret i1 false686;687entry:688 %cmp = icmp sgt i32 %a, 5689 br i1 %cmp, label %a_guard, label %out690 691a_guard:692 %cmp2 = icmp sgt i32 %b, 20693 br i1 %cmp2, label %b_guard, label %out694 695b_guard:696 %sel_cmp = icmp uge i32 %a, %b697 %max = select i1 %sel_cmp, i32 %a, i32 %b698 %res = icmp eq i32 %max, 7699 ret i1 %res700out:701 ret i1 false702}703 704define i1 @umin_lhs_overdefined_rhs_const(i32 %a) {705; CHECK-LABEL: define i1 @umin_lhs_overdefined_rhs_const706; CHECK-SAME: (i32 [[A:%.*]]) {707; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A]], 42708; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 [[A]], i32 42709; CHECK-NEXT: ret i1 true710;711 %cmp = icmp ult i32 %a, 42712 %sel = select i1 %cmp, i32 %a, i32 42713 %cmp2 = icmp ule i32 %sel, 42714 ret i1 %cmp2715}716 717define i1 @umin_rhs_overdefined_lhs_const(i32 %a) {718; CHECK-LABEL: define i1 @umin_rhs_overdefined_lhs_const719; CHECK-SAME: (i32 [[A:%.*]]) {720; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[A]], 42721; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 42, i32 [[A]]722; CHECK-NEXT: ret i1 true723;724 %cmp = icmp uge i32 %a, 42725 %sel = select i1 %cmp, i32 42, i32 %a726 %cmp2 = icmp ule i32 %sel, 42727 ret i1 %cmp2728}729 730define i1 @umin_lhs_overdefined_rhs_range(i32 %a, i32 %b) {731; CHECK-LABEL: define i1 @umin_lhs_overdefined_rhs_range732; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {733; CHECK-NEXT: [[ASSUME:%.*]] = icmp ult i32 [[B]], 42734; CHECK-NEXT: call void @llvm.assume(i1 [[ASSUME]])735; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A]], [[B]]736; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 [[A]], i32 [[B]]737; CHECK-NEXT: ret i1 true738;739 %assume = icmp ult i32 %b, 42740 call void @llvm.assume(i1 %assume)741 %cmp = icmp ult i32 %a, %b742 %sel = select i1 %cmp, i32 %a, i32 %b743 %cmp2 = icmp ult i32 %sel, 42744 ret i1 %cmp2745}746 747define i1 @umin_rhs_overdefined_lhs_range(i32 %a, i32 %b) {748; CHECK-LABEL: define i1 @umin_rhs_overdefined_lhs_range749; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {750; CHECK-NEXT: [[ASSUME:%.*]] = icmp ult i32 [[B]], 42751; CHECK-NEXT: call void @llvm.assume(i1 [[ASSUME]])752; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[A]], [[B]]753; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 [[B]], i32 [[A]]754; CHECK-NEXT: ret i1 true755;756 %assume = icmp ult i32 %b, 42757 call void @llvm.assume(i1 %assume)758 %cmp = icmp uge i32 %a, %b759 %sel = select i1 %cmp, i32 %b, i32 %a760 %cmp2 = icmp ult i32 %sel, 42761 ret i1 %cmp2762}763 764define i1 @clamp_low1(i32 noundef %a) {765; CHECK-LABEL: define i1 @clamp_low1766; CHECK-SAME: (i32 noundef [[A:%.*]]) {767; CHECK-NEXT: entry:768; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[A]], 5769; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]770; CHECK: a_guard:771; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp eq i32 [[A]], 5772; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], -1773; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 5, i32 [[ADD]]774; CHECK-NEXT: ret i1 false775; CHECK: out:776; CHECK-NEXT: ret i1 false777;778entry:779 %cmp = icmp sge i32 %a, 5780 br i1 %cmp, label %a_guard, label %out781 782a_guard:783 %sel_cmp = icmp eq i32 %a, 5784 %add = add i32 %a, -1785 %sel = select i1 %sel_cmp, i32 5, i32 %add786 %res = icmp eq i32 %sel, 4787 ret i1 %res788out:789 ret i1 false790}791 792define i1 @clamp_low2(i32 noundef %a) {793; CHECK-LABEL: define i1 @clamp_low2794; CHECK-SAME: (i32 noundef [[A:%.*]]) {795; CHECK-NEXT: entry:796; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[A]], 5797; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]798; CHECK: a_guard:799; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp ne i32 [[A]], 5800; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], -1801; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 [[ADD]], i32 5802; CHECK-NEXT: ret i1 false803; CHECK: out:804; CHECK-NEXT: ret i1 false805;806entry:807 %cmp = icmp sge i32 %a, 5808 br i1 %cmp, label %a_guard, label %out809 810a_guard:811 %sel_cmp = icmp ne i32 %a, 5812 %add = add i32 %a, -1813 %sel = select i1 %sel_cmp, i32 %add, i32 5814 %res = icmp eq i32 %sel, 4815 ret i1 %res816out:817 ret i1 false818}819 820define i1 @clamp_low3(i32 noundef %a) {821; CHECK-LABEL: define i1 @clamp_low3822; CHECK-SAME: (i32 noundef [[A:%.*]]) {823; CHECK-NEXT: entry:824; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[A]], 5825; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]826; CHECK: a_guard:827; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp samesign ugt i32 [[A]], 5828; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], -1829; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 [[ADD]], i32 5830; CHECK-NEXT: ret i1 false831; CHECK: out:832; CHECK-NEXT: ret i1 false833;834entry:835 %cmp = icmp sge i32 %a, 5836 br i1 %cmp, label %a_guard, label %out837 838a_guard:839 %sel_cmp = icmp sgt i32 %a, 5840 %add = add i32 %a, -1841 %sel = select i1 %sel_cmp, i32 %add, i32 5842 %res = icmp eq i32 %sel, 4843 ret i1 %res844out:845 ret i1 false846}847 848define i1 @clamp_low4(i32 noundef %a) {849; CHECK-LABEL: define i1 @clamp_low4850; CHECK-SAME: (i32 noundef [[A:%.*]]) {851; CHECK-NEXT: entry:852; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[A]], 5853; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]854; CHECK: a_guard:855; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp samesign ule i32 [[A]], 5856; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], -1857; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 5, i32 [[ADD]]858; CHECK-NEXT: ret i1 false859; CHECK: out:860; CHECK-NEXT: ret i1 false861;862entry:863 %cmp = icmp sge i32 %a, 5864 br i1 %cmp, label %a_guard, label %out865 866a_guard:867 %sel_cmp = icmp sle i32 %a, 5868 %add = add i32 %a, -1869 %sel = select i1 %sel_cmp, i32 5, i32 %add870 %res = icmp eq i32 %sel, 4871 ret i1 %res872out:873 ret i1 false874}875 876define i1 @clamp_high1(i32 noundef %a) {877; CHECK-LABEL: define i1 @clamp_high1878; CHECK-SAME: (i32 noundef [[A:%.*]]) {879; CHECK-NEXT: entry:880; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[A]], 5881; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]882; CHECK: a_guard:883; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp eq i32 [[A]], 5884; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 1885; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 5, i32 [[ADD]]886; CHECK-NEXT: ret i1 false887; CHECK: out:888; CHECK-NEXT: ret i1 false889;890entry:891 %cmp = icmp sle i32 %a, 5892 br i1 %cmp, label %a_guard, label %out893 894a_guard:895 %sel_cmp = icmp eq i32 %a, 5896 %add = add i32 %a, 1897 %sel = select i1 %sel_cmp, i32 5, i32 %add898 %res = icmp eq i32 %sel, 6899 ret i1 %res900out:901 ret i1 false902}903 904define i1 @clamp_high1_or(i32 noundef %a) {905; CHECK-LABEL: define i1 @clamp_high1_or906; CHECK-SAME: (i32 noundef [[A:%.*]]) {907; CHECK-NEXT: entry:908; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[A]], 5909; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]910; CHECK: a_guard:911; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp eq i32 [[A]], 5912; CHECK-NEXT: [[ADD:%.*]] = or disjoint i32 [[A]], 1913; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 5, i32 [[ADD]]914; CHECK-NEXT: ret i1 false915; CHECK: out:916; CHECK-NEXT: ret i1 false917;918entry:919 %cmp = icmp sle i32 %a, 5920 br i1 %cmp, label %a_guard, label %out921 922a_guard:923 %sel_cmp = icmp eq i32 %a, 5924 %add = or disjoint i32 %a, 1925 %sel = select i1 %sel_cmp, i32 5, i32 %add926 %res = icmp eq i32 %sel, 6927 ret i1 %res928out:929 ret i1 false930}931 932define i1 @clamp_high2(i32 noundef %a) {933; CHECK-LABEL: define i1 @clamp_high2934; CHECK-SAME: (i32 noundef [[A:%.*]]) {935; CHECK-NEXT: entry:936; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[A]], 5937; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]938; CHECK: a_guard:939; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp ne i32 [[A]], 5940; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 1941; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 [[ADD]], i32 5942; CHECK-NEXT: ret i1 false943; CHECK: out:944; CHECK-NEXT: ret i1 false945;946entry:947 %cmp = icmp sle i32 %a, 5948 br i1 %cmp, label %a_guard, label %out949 950a_guard:951 %sel_cmp = icmp ne i32 %a, 5952 %add = add i32 %a, 1953 %sel = select i1 %sel_cmp, i32 %add, i32 5954 %res = icmp eq i32 %sel, 6955 ret i1 %res956out:957 ret i1 false958}959 960 961define i1 @clamp_high2_or_disjoint(i32 noundef %a) {962; CHECK-LABEL: define i1 @clamp_high2_or_disjoint963; CHECK-SAME: (i32 noundef [[A:%.*]]) {964; CHECK-NEXT: entry:965; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[A]], 5966; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]967; CHECK: a_guard:968; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp ne i32 [[A]], 5969; CHECK-NEXT: [[ADD:%.*]] = or disjoint i32 [[A]], 1970; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 [[ADD]], i32 5971; CHECK-NEXT: ret i1 false972; CHECK: out:973; CHECK-NEXT: ret i1 false974;975entry:976 %cmp = icmp sle i32 %a, 5977 br i1 %cmp, label %a_guard, label %out978 979a_guard:980 %sel_cmp = icmp ne i32 %a, 5981 %add = or disjoint i32 %a, 1982 %sel = select i1 %sel_cmp, i32 %add, i32 5983 %res = icmp eq i32 %sel, 6984 ret i1 %res985out:986 ret i1 false987}988 989 990define i1 @clamp_high3(i32 noundef %a) {991; CHECK-LABEL: define i1 @clamp_high3992; CHECK-SAME: (i32 noundef [[A:%.*]]) {993; CHECK-NEXT: entry:994; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[A]], 5995; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]996; CHECK: a_guard:997; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp slt i32 [[A]], 5998; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 1999; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 [[ADD]], i32 51000; CHECK-NEXT: ret i1 false1001; CHECK: out:1002; CHECK-NEXT: ret i1 false1003;1004entry:1005 %cmp = icmp sle i32 %a, 51006 br i1 %cmp, label %a_guard, label %out1007 1008a_guard:1009 %sel_cmp = icmp slt i32 %a, 51010 %add = add i32 %a, 11011 %sel = select i1 %sel_cmp, i32 %add, i32 51012 %res = icmp eq i32 %sel, 61013 ret i1 %res1014out:1015 ret i1 false1016}1017 1018define i1 @clamp_high4(i32 noundef %a) {1019; CHECK-LABEL: define i1 @clamp_high41020; CHECK-SAME: (i32 noundef [[A:%.*]]) {1021; CHECK-NEXT: entry:1022; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[A]], 51023; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]1024; CHECK: a_guard:1025; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp sge i32 [[A]], 51026; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 11027; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 5, i32 [[ADD]]1028; CHECK-NEXT: ret i1 false1029; CHECK: out:1030; CHECK-NEXT: ret i1 false1031;1032entry:1033 %cmp = icmp sle i32 %a, 51034 br i1 %cmp, label %a_guard, label %out1035 1036a_guard:1037 %sel_cmp = icmp sge i32 %a, 51038 %add = add i32 %a, 11039 %sel = select i1 %sel_cmp, i32 5, i32 %add1040 %res = icmp eq i32 %sel, 61041 ret i1 %res1042out:1043 ret i1 false1044}1045 1046; Just showing arbitrary constants work, not really a clamp1047define i1 @not_clamp_high(i32 noundef %a) {1048; CHECK-LABEL: define i1 @not_clamp_high1049; CHECK-SAME: (i32 noundef [[A:%.*]]) {1050; CHECK-NEXT: entry:1051; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[A]], 51052; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]1053; CHECK: a_guard:1054; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp ne i32 [[A]], 51055; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 1001056; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 [[ADD]], i32 51057; CHECK-NEXT: ret i1 false1058; CHECK: out:1059; CHECK-NEXT: ret i1 false1060;1061entry:1062 %cmp = icmp sle i32 %a, 51063 br i1 %cmp, label %a_guard, label %out1064 1065a_guard:1066 %sel_cmp = icmp ne i32 %a, 51067 %add = add i32 %a, 1001068 %sel = select i1 %sel_cmp, i32 %add, i32 51069 %res = icmp eq i32 %sel, 1051070 ret i1 %res1071out:1072 ret i1 false1073}1074 1075define void @abs1(i32 %a, ptr %p) {1076; CHECK-LABEL: define void @abs11077; CHECK-SAME: (i32 [[A:%.*]], ptr [[P:%.*]]) {1078; CHECK-NEXT: entry:1079; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[A]], 101080; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[A]], -201081; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]]1082; CHECK-NEXT: br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]]1083; CHECK: guard:1084; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 0, [[A]]1085; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A]], 01086; CHECK-NEXT: [[ABS:%.*]] = select i1 [[CMP]], i32 [[SUB]], i32 [[A]]1087; CHECK-NEXT: store i1 true, ptr [[P]], align 11088; CHECK-NEXT: [[C2:%.*]] = icmp samesign ult i32 [[ABS]], 191089; CHECK-NEXT: store i1 [[C2]], ptr [[P]], align 11090; CHECK-NEXT: store i1 true, ptr [[P]], align 11091; CHECK-NEXT: [[C4:%.*]] = icmp samesign uge i32 [[ABS]], 11092; CHECK-NEXT: store i1 [[C4]], ptr [[P]], align 11093; CHECK-NEXT: br label [[EXIT]]1094; CHECK: exit:1095; CHECK-NEXT: ret void1096;1097entry:1098 %cmp1 = icmp slt i32 %a, 101099 %cmp2 = icmp sgt i32 %a, -201100 %and = and i1 %cmp1, %cmp21101 br i1 %and, label %guard, label %exit1102 1103guard:1104 %sub = sub i32 0, %a1105 %cmp = icmp slt i32 %a, 01106 %abs = select i1 %cmp, i32 %sub, i32 %a1107 %c1 = icmp slt i32 %abs, 201108 store i1 %c1, ptr %p1109 %c2 = icmp slt i32 %abs, 191110 store i1 %c2, ptr %p1111 %c3 = icmp sge i32 %abs, 01112 store i1 %c3, ptr %p1113 %c4 = icmp sge i32 %abs, 11114 store i1 %c4, ptr %p1115 br label %exit1116 1117exit:1118 ret void1119}1120 1121define void @abs2(i32 %a, ptr %p) {1122; CHECK-LABEL: define void @abs21123; CHECK-SAME: (i32 [[A:%.*]], ptr [[P:%.*]]) {1124; CHECK-NEXT: entry:1125; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[A]], 101126; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[A]], -201127; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]]1128; CHECK-NEXT: br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]]1129; CHECK: guard:1130; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 0, [[A]]1131; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[A]], 01132; CHECK-NEXT: [[ABS:%.*]] = select i1 [[CMP]], i32 [[A]], i32 [[SUB]]1133; CHECK-NEXT: store i1 true, ptr [[P]], align 11134; CHECK-NEXT: [[C2:%.*]] = icmp samesign ult i32 [[ABS]], 191135; CHECK-NEXT: store i1 [[C2]], ptr [[P]], align 11136; CHECK-NEXT: store i1 true, ptr [[P]], align 11137; CHECK-NEXT: [[C4:%.*]] = icmp samesign uge i32 [[ABS]], 11138; CHECK-NEXT: store i1 [[C4]], ptr [[P]], align 11139; CHECK-NEXT: br label [[EXIT]]1140; CHECK: exit:1141; CHECK-NEXT: ret void1142;1143entry:1144 %cmp1 = icmp slt i32 %a, 101145 %cmp2 = icmp sgt i32 %a, -201146 %and = and i1 %cmp1, %cmp21147 br i1 %and, label %guard, label %exit1148 1149guard:1150 %sub = sub i32 0, %a1151 %cmp = icmp sge i32 %a, 01152 %abs = select i1 %cmp, i32 %a, i32 %sub1153 %c1 = icmp slt i32 %abs, 201154 store i1 %c1, ptr %p1155 %c2 = icmp slt i32 %abs, 191156 store i1 %c2, ptr %p1157 %c3 = icmp sge i32 %abs, 01158 store i1 %c3, ptr %p1159 %c4 = icmp sge i32 %abs, 11160 store i1 %c4, ptr %p1161 br label %exit1162 1163exit:1164 ret void1165}1166 1167define void @nabs1(i32 %a, ptr %p) {1168; CHECK-LABEL: define void @nabs11169; CHECK-SAME: (i32 [[A:%.*]], ptr [[P:%.*]]) {1170; CHECK-NEXT: entry:1171; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[A]], 101172; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[A]], -201173; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]]1174; CHECK-NEXT: br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]]1175; CHECK: guard:1176; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 0, [[A]]1177; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A]], 01178; CHECK-NEXT: [[NABS:%.*]] = select i1 [[CMP]], i32 [[SUB]], i32 [[A]]1179; CHECK-NEXT: store i1 true, ptr [[P]], align 11180; CHECK-NEXT: [[C2:%.*]] = icmp sgt i32 [[NABS]], -191181; CHECK-NEXT: store i1 [[C2]], ptr [[P]], align 11182; CHECK-NEXT: store i1 true, ptr [[P]], align 11183; CHECK-NEXT: [[C4:%.*]] = icmp sle i32 [[NABS]], -11184; CHECK-NEXT: store i1 [[C4]], ptr [[P]], align 11185; CHECK-NEXT: br label [[EXIT]]1186; CHECK: exit:1187; CHECK-NEXT: ret void1188;1189entry:1190 %cmp1 = icmp slt i32 %a, 101191 %cmp2 = icmp sgt i32 %a, -201192 %and = and i1 %cmp1, %cmp21193 br i1 %and, label %guard, label %exit1194 1195guard:1196 %sub = sub i32 0, %a1197 %cmp = icmp sgt i32 %a, 01198 %nabs = select i1 %cmp, i32 %sub, i32 %a1199 %c1 = icmp sgt i32 %nabs, -201200 store i1 %c1, ptr %p1201 %c2 = icmp sgt i32 %nabs, -191202 store i1 %c2, ptr %p1203 %c3 = icmp sle i32 %nabs, 01204 store i1 %c3, ptr %p1205 %c4 = icmp sle i32 %nabs, -11206 store i1 %c4, ptr %p1207 br label %exit1208 1209exit:1210 ret void1211}1212 1213define void @nabs2(i32 %a, ptr %p) {1214; CHECK-LABEL: define void @nabs21215; CHECK-SAME: (i32 [[A:%.*]], ptr [[P:%.*]]) {1216; CHECK-NEXT: entry:1217; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[A]], 101218; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[A]], -201219; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]]1220; CHECK-NEXT: br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]]1221; CHECK: guard:1222; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 0, [[A]]1223; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A]], 01224; CHECK-NEXT: [[NABS:%.*]] = select i1 [[CMP]], i32 [[A]], i32 [[SUB]]1225; CHECK-NEXT: store i1 true, ptr [[P]], align 11226; CHECK-NEXT: [[C2:%.*]] = icmp sgt i32 [[NABS]], -191227; CHECK-NEXT: store i1 [[C2]], ptr [[P]], align 11228; CHECK-NEXT: store i1 true, ptr [[P]], align 11229; CHECK-NEXT: [[C4:%.*]] = icmp sle i32 [[NABS]], -11230; CHECK-NEXT: store i1 [[C4]], ptr [[P]], align 11231; CHECK-NEXT: br label [[EXIT]]1232; CHECK: exit:1233; CHECK-NEXT: ret void1234;1235entry:1236 %cmp1 = icmp slt i32 %a, 101237 %cmp2 = icmp sgt i32 %a, -201238 %and = and i1 %cmp1, %cmp21239 br i1 %and, label %guard, label %exit1240 1241guard:1242 %sub = sub i32 0, %a1243 %cmp = icmp slt i32 %a, 01244 %nabs = select i1 %cmp, i32 %a, i32 %sub1245 %c1 = icmp sgt i32 %nabs, -201246 store i1 %c1, ptr %p1247 %c2 = icmp sgt i32 %nabs, -191248 store i1 %c2, ptr %p1249 %c3 = icmp sle i32 %nabs, 01250 store i1 %c3, ptr %p1251 %c4 = icmp sle i32 %nabs, -11252 store i1 %c4, ptr %p1253 br label %exit1254 1255exit:1256 ret void1257}1258 1259define i1 @zext_unknown(i8 %a) {1260; CHECK-LABEL: define i1 @zext_unknown1261; CHECK-SAME: (i8 [[A:%.*]]) {1262; CHECK-NEXT: entry:1263; CHECK-NEXT: [[A32:%.*]] = zext i8 [[A]] to i321264; CHECK-NEXT: ret i1 true1265;1266entry:1267 %a32 = zext i8 %a to i321268 %cmp = icmp sle i32 %a32, 2561269 ret i1 %cmp1270}1271 1272define i1 @trunc_unknown(i32 %a) {1273; CHECK-LABEL: define i1 @trunc_unknown1274; CHECK-SAME: (i32 [[A:%.*]]) {1275; CHECK-NEXT: entry:1276; CHECK-NEXT: [[A8:%.*]] = trunc i32 [[A]] to i81277; CHECK-NEXT: [[A32:%.*]] = sext i8 [[A8]] to i321278; CHECK-NEXT: ret i1 true1279;1280entry:1281 %a8 = trunc i32 %a to i81282 %a32 = sext i8 %a8 to i321283 %cmp = icmp sle i32 %a32, 1281284 ret i1 %cmp1285}1286 1287define void @trunc_icmp_ule(i32 %x, ptr %p) {1288; CHECK-LABEL: define void @trunc_icmp_ule1289; CHECK-SAME: (i32 [[X:%.*]], ptr [[P:%.*]]) {1290; CHECK-NEXT: [[T:%.*]] = trunc i32 [[X]] to i81291; CHECK-NEXT: [[C:%.*]] = icmp uge i8 [[T]], 51292; CHECK-NEXT: br i1 [[C]], label [[TRUE:%.*]], label [[FALSE:%.*]]1293; CHECK: true:1294; CHECK-NEXT: store i1 true, ptr [[P]], align 11295; CHECK-NEXT: [[C2:%.*]] = icmp ugt i32 [[X]], 51296; CHECK-NEXT: store i1 [[C2]], ptr [[P]], align 11297; CHECK-NEXT: [[C3:%.*]] = icmp ule i32 [[X]], 51298; CHECK-NEXT: store i1 [[C3]], ptr [[P]], align 11299; CHECK-NEXT: store i1 false, ptr [[P]], align 11300; CHECK-NEXT: ret void1301; CHECK: false:1302; CHECK-NEXT: [[C1_2:%.*]] = icmp uge i32 [[X]], 51303; CHECK-NEXT: store i1 [[C1_2]], ptr [[P]], align 11304; CHECK-NEXT: [[C2_2:%.*]] = icmp ugt i32 [[X]], 51305; CHECK-NEXT: store i1 [[C2_2]], ptr [[P]], align 11306; CHECK-NEXT: [[C3_2:%.*]] = icmp ule i32 [[X]], 51307; CHECK-NEXT: store i1 [[C3_2]], ptr [[P]], align 11308; CHECK-NEXT: [[C4_2:%.*]] = icmp ult i32 [[X]], 51309; CHECK-NEXT: store i1 [[C4_2]], ptr [[P]], align 11310; CHECK-NEXT: ret void1311;1312 %t = trunc i32 %x to i81313 %c = icmp uge i8 %t, 51314 br i1 %c, label %true, label %false1315 1316true:1317 %c1 = icmp uge i32 %x, 51318 store i1 %c1, ptr %p1319 %c2 = icmp ugt i32 %x, 51320 store i1 %c2, ptr %p1321 %c3 = icmp ule i32 %x, 51322 store i1 %c3, ptr %p1323 %c4 = icmp ult i32 %x, 51324 store i1 %c4, ptr %p1325 ret void1326 1327false:1328 %c1.2 = icmp uge i32 %x, 51329 store i1 %c1.2, ptr %p1330 %c2.2 = icmp ugt i32 %x, 51331 store i1 %c2.2, ptr %p1332 %c3.2 = icmp ule i32 %x, 51333 store i1 %c3.2, ptr %p1334 %c4.2 = icmp ult i32 %x, 51335 store i1 %c4.2, ptr %p1336 ret void1337}1338 1339define void @trunc_icmp_eq(i32 %x, ptr %p) {1340; CHECK-LABEL: define void @trunc_icmp_eq1341; CHECK-SAME: (i32 [[X:%.*]], ptr [[P:%.*]]) {1342; CHECK-NEXT: [[T:%.*]] = trunc i32 [[X]] to i81343; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[T]], 51344; CHECK-NEXT: br i1 [[C]], label [[TRUE:%.*]], label [[FALSE:%.*]]1345; CHECK: true:1346; CHECK-NEXT: store i1 true, ptr [[P]], align 11347; CHECK-NEXT: [[C2:%.*]] = icmp ugt i32 [[X]], 51348; CHECK-NEXT: store i1 [[C2]], ptr [[P]], align 11349; CHECK-NEXT: [[C3:%.*]] = icmp ule i32 [[X]], 51350; CHECK-NEXT: store i1 [[C3]], ptr [[P]], align 11351; CHECK-NEXT: store i1 false, ptr [[P]], align 11352; CHECK-NEXT: ret void1353; CHECK: false:1354; CHECK-NEXT: [[C1_2:%.*]] = icmp uge i32 [[X]], 51355; CHECK-NEXT: store i1 [[C1_2]], ptr [[P]], align 11356; CHECK-NEXT: [[C2_2:%.*]] = icmp ugt i32 [[X]], 51357; CHECK-NEXT: store i1 [[C2_2]], ptr [[P]], align 11358; CHECK-NEXT: [[C3_2:%.*]] = icmp ule i32 [[X]], 51359; CHECK-NEXT: store i1 [[C3_2]], ptr [[P]], align 11360; CHECK-NEXT: [[C4_2:%.*]] = icmp ult i32 [[X]], 51361; CHECK-NEXT: store i1 [[C4_2]], ptr [[P]], align 11362; CHECK-NEXT: ret void1363;1364 %t = trunc i32 %x to i81365 %c = icmp eq i8 %t, 51366 br i1 %c, label %true, label %false1367 1368true:1369 %c1 = icmp uge i32 %x, 51370 store i1 %c1, ptr %p1371 %c2 = icmp ugt i32 %x, 51372 store i1 %c2, ptr %p1373 %c3 = icmp ule i32 %x, 51374 store i1 %c3, ptr %p1375 %c4 = icmp ult i32 %x, 51376 store i1 %c4, ptr %p1377 ret void1378 1379false:1380 %c1.2 = icmp uge i32 %x, 51381 store i1 %c1.2, ptr %p1382 %c2.2 = icmp ugt i32 %x, 51383 store i1 %c2.2, ptr %p1384 %c3.2 = icmp ule i32 %x, 51385 store i1 %c3.2, ptr %p1386 %c4.2 = icmp ult i32 %x, 51387 store i1 %c4.2, ptr %p1388 ret void1389}1390 1391; TODO: missed optimization1392; Make sure we exercise non-integer inputs to unary operators (i.e. crash check).1393define i1 @bitcast_unknown(float %a) {1394; CHECK-LABEL: define i1 @bitcast_unknown1395; CHECK-SAME: (float [[A:%.*]]) {1396; CHECK-NEXT: entry:1397; CHECK-NEXT: [[A32:%.*]] = bitcast float [[A]] to i321398; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[A32]], 1281399; CHECK-NEXT: ret i1 [[CMP]]1400;1401entry:1402 %a32 = bitcast float %a to i321403 %cmp = icmp sle i32 %a32, 1281404 ret i1 %cmp1405}1406 1407define i1 @bitcast_unknown2(ptr %p) {1408; CHECK-LABEL: define i1 @bitcast_unknown21409; CHECK-SAME: (ptr [[P:%.*]]) {1410; CHECK-NEXT: entry:1411; CHECK-NEXT: [[P64:%.*]] = ptrtoint ptr [[P]] to i641412; CHECK-NEXT: [[CMP:%.*]] = icmp sle i64 [[P64]], 1281413; CHECK-NEXT: ret i1 [[CMP]]1414;1415entry:1416 %p64 = ptrtoint ptr %p to i641417 %cmp = icmp sle i64 %p64, 1281418 ret i1 %cmp1419}1420 1421 1422define i1 @and_unknown(i32 %a) {1423; CHECK-LABEL: define i1 @and_unknown1424; CHECK-SAME: (i32 [[A:%.*]]) {1425; CHECK-NEXT: entry:1426; CHECK-NEXT: [[AND:%.*]] = and i32 [[A]], 1281427; CHECK-NEXT: ret i1 true1428;1429entry:1430 %and = and i32 %a, 1281431 %cmp = icmp sle i32 %and, 1281432 ret i1 %cmp1433}1434 1435define i1 @lshr_unknown(i32 %a) {1436; CHECK-LABEL: define i1 @lshr_unknown1437; CHECK-SAME: (i32 [[A:%.*]]) {1438; CHECK-NEXT: entry:1439; CHECK-NEXT: [[AND:%.*]] = lshr i32 [[A]], 301440; CHECK-NEXT: ret i1 true1441;1442entry:1443 %and = lshr i32 %a, 301444 %cmp = icmp sle i32 %and, 1281445 ret i1 %cmp1446}1447 1448define i1 @urem_unknown(i32 %a) {1449; CHECK-LABEL: define i1 @urem_unknown1450; CHECK-SAME: (i32 [[A:%.*]]) {1451; CHECK-NEXT: entry:1452; CHECK-NEXT: [[UREM:%.*]] = urem i32 [[A]], 301453; CHECK-NEXT: ret i1 true1454;1455entry:1456 %urem = urem i32 %a, 301457 %cmp = icmp ult i32 %urem, 301458 ret i1 %cmp1459}1460 1461define i1 @srem_unknown(i32 %a, i1 %arg) {1462; CHECK-LABEL: define i1 @srem_unknown1463; CHECK-SAME: (i32 [[A:%.*]], i1 [[ARG:%.*]]) {1464; CHECK-NEXT: entry:1465; CHECK-NEXT: [[SREM:%.*]] = srem i32 [[A]], 301466; CHECK-NEXT: br i1 [[ARG]], label [[EXIT1:%.*]], label [[EXIT2:%.*]]1467; CHECK: exit1:1468; CHECK-NEXT: ret i1 true1469; CHECK: exit2:1470; CHECK-NEXT: ret i1 true1471;1472entry:1473 %srem = srem i32 %a, 301474 %cmp1 = icmp slt i32 %srem, 301475 %cmp2 = icmp sgt i32 %srem, -301476 br i1 %arg, label %exit1, label %exit21477exit1:1478 ret i1 %cmp11479exit2:1480 ret i1 %cmp21481}1482 1483define i1 @sdiv_unknown(i32 %a, i1 %arg) {1484; CHECK-LABEL: define i1 @sdiv_unknown1485; CHECK-SAME: (i32 [[A:%.*]], i1 [[ARG:%.*]]) {1486; CHECK-NEXT: entry:1487; CHECK-NEXT: [[SREM:%.*]] = sdiv i32 [[A]], 1231488; CHECK-NEXT: br i1 [[ARG]], label [[EXIT1:%.*]], label [[EXIT2:%.*]]1489; CHECK: exit1:1490; CHECK-NEXT: ret i1 true1491; CHECK: exit2:1492; CHECK-NEXT: ret i1 true1493;1494entry:1495 %srem = sdiv i32 %a, 1231496 %cmp1 = icmp slt i32 %srem, 174592171497 %cmp2 = icmp sgt i32 %srem, -174592171498 br i1 %arg, label %exit1, label %exit21499exit1:1500 ret i1 %cmp11501exit2:1502 ret i1 %cmp21503}1504 1505define i1 @uadd_sat_unknown(i32 %a, i1 %arg) {1506; CHECK-LABEL: define i1 @uadd_sat_unknown1507; CHECK-SAME: (i32 [[A:%.*]], i1 [[ARG:%.*]]) {1508; CHECK-NEXT: entry:1509; CHECK-NEXT: [[VAL:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[A]], i32 100)1510; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i32 [[VAL]], 1001511; CHECK-NEXT: br i1 [[ARG]], label [[EXIT1:%.*]], label [[EXIT2:%.*]]1512; CHECK: exit1:1513; CHECK-NEXT: ret i1 true1514; CHECK: exit2:1515; CHECK-NEXT: ret i1 [[CMP2]]1516;1517entry:1518 %val = call i32 @llvm.uadd.sat.i32(i32 %a, i32 100)1519 %cmp1 = icmp uge i32 %val, 1001520 %cmp2 = icmp ugt i32 %val, 1001521 br i1 %arg, label %exit1, label %exit21522exit1:1523 ret i1 %cmp11524exit2:1525 ret i1 %cmp21526}1527 1528define i1 @usub_sat_unknown(i32 %a, i1 %arg) {1529; CHECK-LABEL: define i1 @usub_sat_unknown1530; CHECK-SAME: (i32 [[A:%.*]], i1 [[ARG:%.*]]) {1531; CHECK-NEXT: entry:1532; CHECK-NEXT: [[VAL:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[A]], i32 100)1533; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[VAL]], -1011534; CHECK-NEXT: br i1 [[ARG]], label [[EXIT1:%.*]], label [[EXIT2:%.*]]1535; CHECK: exit1:1536; CHECK-NEXT: ret i1 true1537; CHECK: exit2:1538; CHECK-NEXT: ret i1 [[CMP2]]1539;1540entry:1541 %val = call i32 @llvm.usub.sat.i32(i32 %a, i32 100)1542 %cmp1 = icmp ule i32 %val, 42949671951543 %cmp2 = icmp ult i32 %val, 42949671951544 br i1 %arg, label %exit1, label %exit21545exit1:1546 ret i1 %cmp11547exit2:1548 ret i1 %cmp21549}1550 1551define i1 @sadd_sat_unknown(i32 %a, i1 %arg) {1552; CHECK-LABEL: define i1 @sadd_sat_unknown1553; CHECK-SAME: (i32 [[A:%.*]], i1 [[ARG:%.*]]) {1554; CHECK-NEXT: entry:1555; CHECK-NEXT: [[VAL:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[A]], i32 100)1556; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[VAL]], -21474835481557; CHECK-NEXT: br i1 [[ARG]], label [[EXIT1:%.*]], label [[EXIT2:%.*]]1558; CHECK: exit1:1559; CHECK-NEXT: ret i1 true1560; CHECK: exit2:1561; CHECK-NEXT: ret i1 [[CMP2]]1562;1563entry:1564 %val = call i32 @llvm.sadd.sat.i32(i32 %a, i32 100)1565 %cmp1 = icmp sge i32 %val, -21474835481566 %cmp2 = icmp sgt i32 %val, -21474835481567 br i1 %arg, label %exit1, label %exit21568exit1:1569 ret i1 %cmp11570exit2:1571 ret i1 %cmp21572}1573 1574define i1 @ssub_sat_unknown(i32 %a, i1 %arg) {1575; CHECK-LABEL: define i1 @ssub_sat_unknown1576; CHECK-SAME: (i32 [[A:%.*]], i1 [[ARG:%.*]]) {1577; CHECK-NEXT: entry:1578; CHECK-NEXT: [[VAL:%.*]] = call i32 @llvm.ssub.sat.i32(i32 [[A]], i32 100)1579; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[VAL]], 21474835471580; CHECK-NEXT: br i1 [[ARG]], label [[EXIT1:%.*]], label [[EXIT2:%.*]]1581; CHECK: exit1:1582; CHECK-NEXT: ret i1 true1583; CHECK: exit2:1584; CHECK-NEXT: ret i1 [[CMP2]]1585;1586entry:1587 %val = call i32 @llvm.ssub.sat.i32(i32 %a, i32 100)1588 %cmp1 = icmp sle i32 %val, 21474835471589 %cmp2 = icmp slt i32 %val, 21474835471590 br i1 %arg, label %exit1, label %exit21591exit1:1592 ret i1 %cmp11593exit2:1594 ret i1 %cmp21595}1596 1597define void @select_and(i32 %a, ptr %p) {1598; CHECK-LABEL: define void @select_and1599; CHECK-SAME: (i32 [[A:%.*]], ptr [[P:%.*]]) {1600; CHECK-NEXT: entry:1601; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[A]], -101602; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[A]], 101603; CHECK-NEXT: [[AND:%.*]] = select i1 [[CMP1]], i1 [[CMP2]], i1 false1604; CHECK-NEXT: br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]]1605; CHECK: guard:1606; CHECK-NEXT: store i1 false, ptr [[P]], align 11607; CHECK-NEXT: store i1 false, ptr [[P]], align 11608; CHECK-NEXT: br label [[EXIT]]1609; CHECK: exit:1610; CHECK-NEXT: ret void1611;1612entry:1613 %cmp1 = icmp sgt i32 %a, -101614 %cmp2 = icmp slt i32 %a, 101615 %and = select i1 %cmp1, i1 %cmp2, i1 false1616 br i1 %and, label %guard, label %exit1617 1618guard:1619 %c1 = icmp sgt i32 %a, 201620 store i1 %c1, ptr %p1621 %c2 = icmp slt i32 %a, -201622 store i1 %c2, ptr %p1623 br label %exit1624 1625exit:1626 ret void1627}1628 1629define void @select_and_wrong_const(i32 %a, ptr %p) {1630; CHECK-LABEL: define void @select_and_wrong_const1631; CHECK-SAME: (i32 [[A:%.*]], ptr [[P:%.*]]) {1632; CHECK-NEXT: entry:1633; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[A]], -101634; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[A]], 101635; CHECK-NEXT: [[AND:%.*]] = select i1 [[CMP1]], i1 [[CMP2]], i1 true1636; CHECK-NEXT: br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]]1637; CHECK: guard:1638; CHECK-NEXT: [[C1:%.*]] = icmp sgt i32 [[A]], 201639; CHECK-NEXT: store i1 [[C1]], ptr [[P]], align 11640; CHECK-NEXT: [[C2:%.*]] = icmp slt i32 [[A]], -201641; CHECK-NEXT: store i1 [[C2]], ptr [[P]], align 11642; CHECK-NEXT: br label [[EXIT]]1643; CHECK: exit:1644; CHECK-NEXT: ret void1645;1646entry:1647 %cmp1 = icmp sgt i32 %a, -101648 %cmp2 = icmp slt i32 %a, 101649 %and = select i1 %cmp1, i1 %cmp2, i1 true1650 br i1 %and, label %guard, label %exit1651 1652guard:1653 %c1 = icmp sgt i32 %a, 201654 store i1 %c1, ptr %p1655 %c2 = icmp slt i32 %a, -201656 store i1 %c2, ptr %p1657 br label %exit1658 1659exit:1660 ret void1661}1662 1663define void @select_and_wrong_operand(i32 %a, ptr %p) {1664; CHECK-LABEL: define void @select_and_wrong_operand1665; CHECK-SAME: (i32 [[A:%.*]], ptr [[P:%.*]]) {1666; CHECK-NEXT: entry:1667; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[A]], -101668; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[A]], 101669; CHECK-NEXT: [[AND:%.*]] = select i1 [[CMP1]], i1 false, i1 [[CMP2]]1670; CHECK-NEXT: br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]]1671; CHECK: guard:1672; CHECK-NEXT: [[C1:%.*]] = icmp sgt i32 [[A]], 201673; CHECK-NEXT: store i1 [[C1]], ptr [[P]], align 11674; CHECK-NEXT: [[C2:%.*]] = icmp slt i32 [[A]], -201675; CHECK-NEXT: store i1 [[C2]], ptr [[P]], align 11676; CHECK-NEXT: br label [[EXIT]]1677; CHECK: exit:1678; CHECK-NEXT: ret void1679;1680entry:1681 %cmp1 = icmp sgt i32 %a, -101682 %cmp2 = icmp slt i32 %a, 101683 %and = select i1 %cmp1, i1 false, i1 %cmp21684 br i1 %and, label %guard, label %exit1685 1686guard:1687 %c1 = icmp sgt i32 %a, 201688 store i1 %c1, ptr %p1689 %c2 = icmp slt i32 %a, -201690 store i1 %c2, ptr %p1691 br label %exit1692 1693exit:1694 ret void1695}1696 1697define void @select_or(i32 %a, ptr %p) {1698; CHECK-LABEL: define void @select_or1699; CHECK-SAME: (i32 [[A:%.*]], ptr [[P:%.*]]) {1700; CHECK-NEXT: entry:1701; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[A]], -101702; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[A]], 101703; CHECK-NEXT: [[OR:%.*]] = select i1 [[CMP1]], i1 true, i1 [[CMP2]]1704; CHECK-NEXT: br i1 [[OR]], label [[EXIT:%.*]], label [[GUARD:%.*]]1705; CHECK: guard:1706; CHECK-NEXT: store i1 false, ptr [[P]], align 11707; CHECK-NEXT: store i1 false, ptr [[P]], align 11708; CHECK-NEXT: br label [[EXIT]]1709; CHECK: exit:1710; CHECK-NEXT: ret void1711;1712entry:1713 %cmp1 = icmp slt i32 %a, -101714 %cmp2 = icmp sgt i32 %a, 101715 %or = select i1 %cmp1, i1 true, i1 %cmp21716 br i1 %or, label %exit, label %guard1717 1718guard:1719 %c1 = icmp sgt i32 %a, 201720 store i1 %c1, ptr %p1721 %c2 = icmp slt i32 %a, -201722 store i1 %c2, ptr %p1723 br label %exit1724 1725exit:1726 ret void1727}1728 1729define void @select_or_wrong_const(i32 %a, ptr %p) {1730; CHECK-LABEL: define void @select_or_wrong_const1731; CHECK-SAME: (i32 [[A:%.*]], ptr [[P:%.*]]) {1732; CHECK-NEXT: entry:1733; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[A]], -101734; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[A]], 101735; CHECK-NEXT: [[OR:%.*]] = select i1 [[CMP1]], i1 false, i1 [[CMP2]]1736; CHECK-NEXT: br i1 [[OR]], label [[EXIT:%.*]], label [[GUARD:%.*]]1737; CHECK: guard:1738; CHECK-NEXT: [[C1:%.*]] = icmp sgt i32 [[A]], 201739; CHECK-NEXT: store i1 [[C1]], ptr [[P]], align 11740; CHECK-NEXT: [[C2:%.*]] = icmp slt i32 [[A]], -201741; CHECK-NEXT: store i1 [[C2]], ptr [[P]], align 11742; CHECK-NEXT: br label [[EXIT]]1743; CHECK: exit:1744; CHECK-NEXT: ret void1745;1746entry:1747 %cmp1 = icmp slt i32 %a, -101748 %cmp2 = icmp sgt i32 %a, 101749 %or = select i1 %cmp1, i1 false, i1 %cmp21750 br i1 %or, label %exit, label %guard1751 1752guard:1753 %c1 = icmp sgt i32 %a, 201754 store i1 %c1, ptr %p1755 %c2 = icmp slt i32 %a, -201756 store i1 %c2, ptr %p1757 br label %exit1758 1759exit:1760 ret void1761}1762 1763define void @select_or_wrong_operand(i32 %a, ptr %p) {1764; CHECK-LABEL: define void @select_or_wrong_operand1765; CHECK-SAME: (i32 [[A:%.*]], ptr [[P:%.*]]) {1766; CHECK-NEXT: entry:1767; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[A]], -101768; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[A]], 101769; CHECK-NEXT: [[OR:%.*]] = select i1 [[CMP1]], i1 [[CMP2]], i1 true1770; CHECK-NEXT: br i1 [[OR]], label [[EXIT:%.*]], label [[GUARD:%.*]]1771; CHECK: guard:1772; CHECK-NEXT: [[C1:%.*]] = icmp sgt i32 [[A]], 201773; CHECK-NEXT: store i1 [[C1]], ptr [[P]], align 11774; CHECK-NEXT: [[C2:%.*]] = icmp slt i32 [[A]], -201775; CHECK-NEXT: store i1 [[C2]], ptr [[P]], align 11776; CHECK-NEXT: br label [[EXIT]]1777; CHECK: exit:1778; CHECK-NEXT: ret void1779;1780entry:1781 %cmp1 = icmp slt i32 %a, -101782 %cmp2 = icmp sgt i32 %a, 101783 %or = select i1 %cmp1, i1 %cmp2, i1 true1784 br i1 %or, label %exit, label %guard1785 1786guard:1787 %c1 = icmp sgt i32 %a, 201788 store i1 %c1, ptr %p1789 %c2 = icmp slt i32 %a, -201790 store i1 %c2, ptr %p1791 br label %exit1792 1793exit:1794 ret void1795}1796 1797define void @or_union(i32 %a, ptr %p) {1798; CHECK-LABEL: define void @or_union1799; CHECK-SAME: (i32 [[A:%.*]], ptr [[P:%.*]]) {1800; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[A]], 101801; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[A]], 121802; CHECK-NEXT: [[OR:%.*]] = or i1 [[CMP1]], [[CMP2]]1803; CHECK-NEXT: br i1 [[OR]], label [[GUARD:%.*]], label [[EXIT:%.*]]1804; CHECK: guard:1805; CHECK-NEXT: store i1 false, ptr [[P]], align 11806; CHECK-NEXT: [[C2:%.*]] = icmp eq i32 [[A]], 101807; CHECK-NEXT: store i1 [[C2]], ptr [[P]], align 11808; CHECK-NEXT: [[C3:%.*]] = icmp eq i32 [[A]], 111809; CHECK-NEXT: store i1 [[C3]], ptr [[P]], align 11810; CHECK-NEXT: [[C4:%.*]] = icmp eq i32 [[A]], 121811; CHECK-NEXT: store i1 [[C4]], ptr [[P]], align 11812; CHECK-NEXT: store i1 false, ptr [[P]], align 11813; CHECK-NEXT: br label [[EXIT]]1814; CHECK: exit:1815; CHECK-NEXT: ret void1816;1817 %cmp1 = icmp eq i32 %a, 101818 %cmp2 = icmp eq i32 %a, 121819 %or = or i1 %cmp1, %cmp21820 br i1 %or, label %guard, label %exit1821 1822guard:1823 %c1 = icmp eq i32 %a, 91824 store i1 %c1, ptr %p1825 %c2 = icmp eq i32 %a, 101826 store i1 %c2, ptr %p1827 %c3 = icmp eq i32 %a, 111828 store i1 %c3, ptr %p1829 %c4 = icmp eq i32 %a, 121830 store i1 %c4, ptr %p1831 %c5 = icmp eq i32 %a, 131832 store i1 %c5, ptr %p1833 br label %exit1834 1835exit:1836 ret void1837}1838 1839define i1 @or_union_unknown_cond(i32 %a, i1 %c) {1840; CHECK-LABEL: define i1 @or_union_unknown_cond1841; CHECK-SAME: (i32 [[A:%.*]], i1 [[C:%.*]]) {1842; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[A]], 101843; CHECK-NEXT: [[OR:%.*]] = or i1 [[CMP1]], [[C]]1844; CHECK-NEXT: br i1 [[OR]], label [[GUARD:%.*]], label [[EXIT:%.*]]1845; CHECK: guard:1846; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[A]], 101847; CHECK-NEXT: ret i1 [[CMP2]]1848; CHECK: exit:1849; CHECK-NEXT: ret i1 false1850;1851 %cmp1 = icmp eq i32 %a, 101852 %or = or i1 %cmp1, %c1853 br i1 %or, label %guard, label %exit1854 1855guard:1856 %cmp2 = icmp eq i32 %a, 101857 ret i1 %cmp21858 1859exit:1860 ret i1 false1861}1862 1863define void @and_union(i32 %a, ptr %p) {1864; CHECK-LABEL: define void @and_union1865; CHECK-SAME: (i32 [[A:%.*]], ptr [[P:%.*]]) {1866; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i32 [[A]], 101867; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i32 [[A]], 121868; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]]1869; CHECK-NEXT: br i1 [[AND]], label [[EXIT:%.*]], label [[GUARD:%.*]]1870; CHECK: guard:1871; CHECK-NEXT: store i1 false, ptr [[P]], align 11872; CHECK-NEXT: [[C2:%.*]] = icmp eq i32 [[A]], 101873; CHECK-NEXT: store i1 [[C2]], ptr [[P]], align 11874; CHECK-NEXT: [[C3:%.*]] = icmp eq i32 [[A]], 111875; CHECK-NEXT: store i1 [[C3]], ptr [[P]], align 11876; CHECK-NEXT: [[C4:%.*]] = icmp eq i32 [[A]], 121877; CHECK-NEXT: store i1 [[C4]], ptr [[P]], align 11878; CHECK-NEXT: store i1 false, ptr [[P]], align 11879; CHECK-NEXT: br label [[EXIT]]1880; CHECK: exit:1881; CHECK-NEXT: ret void1882;1883 %cmp1 = icmp ne i32 %a, 101884 %cmp2 = icmp ne i32 %a, 121885 %and = and i1 %cmp1, %cmp21886 br i1 %and, label %exit, label %guard1887 1888guard:1889 %c1 = icmp eq i32 %a, 91890 store i1 %c1, ptr %p1891 %c2 = icmp eq i32 %a, 101892 store i1 %c2, ptr %p1893 %c3 = icmp eq i32 %a, 111894 store i1 %c3, ptr %p1895 %c4 = icmp eq i32 %a, 121896 store i1 %c4, ptr %p1897 %c5 = icmp eq i32 %a, 131898 store i1 %c5, ptr %p1899 br label %exit1900 1901exit:1902 ret void1903}1904 1905define i1 @and_union_unknown_cond(i32 %a, i1 %c) {1906; CHECK-LABEL: define i1 @and_union_unknown_cond1907; CHECK-SAME: (i32 [[A:%.*]], i1 [[C:%.*]]) {1908; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i32 [[A]], 101909; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP1]], [[C]]1910; CHECK-NEXT: br i1 [[AND]], label [[EXIT:%.*]], label [[GUARD:%.*]]1911; CHECK: guard:1912; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[A]], 101913; CHECK-NEXT: ret i1 [[CMP2]]1914; CHECK: exit:1915; CHECK-NEXT: ret i1 false1916;1917 %cmp1 = icmp ne i32 %a, 101918 %and = and i1 %cmp1, %c1919 br i1 %and, label %exit, label %guard1920 1921guard:1922 %cmp2 = icmp eq i32 %a, 101923 ret i1 %cmp21924 1925exit:1926 ret i1 false1927}1928 1929define void @select_assume(i32 %a, i32 %b, i1 %c, ptr %p) {1930; CHECK-LABEL: define void @select_assume1931; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i1 [[C:%.*]], ptr [[P:%.*]]) {1932; CHECK-NEXT: [[C1:%.*]] = icmp ult i32 [[A]], 101933; CHECK-NEXT: call void @llvm.assume(i1 [[C1]])1934; CHECK-NEXT: [[C2:%.*]] = icmp ult i32 [[B]], 201935; CHECK-NEXT: call void @llvm.assume(i1 [[C2]])1936; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i32 [[A]], i32 [[B]]1937; CHECK-NEXT: [[C3:%.*]] = icmp samesign ult i32 [[S]], 191938; CHECK-NEXT: store i1 [[C3]], ptr [[P]], align 11939; CHECK-NEXT: store i1 true, ptr [[P]], align 11940; CHECK-NEXT: ret void1941;1942 %c1 = icmp ult i32 %a, 101943 call void @llvm.assume(i1 %c1)1944 %c2 = icmp ult i32 %b, 201945 call void @llvm.assume(i1 %c2)1946 %s = select i1 %c, i32 %a, i32 %b1947 %c3 = icmp ult i32 %s, 191948 store i1 %c3, ptr %p1949 %c4 = icmp ult i32 %s, 201950 store i1 %c4, ptr %p1951 ret void1952}1953 1954define void @xor(i8 %a, ptr %p) {1955; CHECK-LABEL: define void @xor1956; CHECK-SAME: (i8 [[A:%.*]], ptr [[P:%.*]]) {1957; CHECK-NEXT: [[A_MASK:%.*]] = and i8 [[A]], 151958; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[A_MASK]], -861959; CHECK-NEXT: store i1 true, ptr [[P]], align 11960; CHECK-NEXT: [[C2:%.*]] = icmp samesign ugt i8 [[XOR]], -961961; CHECK-NEXT: store i1 [[C2]], ptr [[P]], align 11962; CHECK-NEXT: store i1 true, ptr [[P]], align 11963; CHECK-NEXT: [[C4:%.*]] = icmp samesign ult i8 [[XOR]], -811964; CHECK-NEXT: store i1 [[C4]], ptr [[P]], align 11965; CHECK-NEXT: ret void1966;1967 %a.mask = and i8 %a, 15 ; 0b0000????1968 %xor = xor i8 %a.mask, 170 ; ^ 0b10101010 == 0b1010????1969 %c1 = icmp uge i8 %xor, 1601970 store i1 %c1, ptr %p1971 %c2 = icmp ugt i8 %xor, 1601972 store i1 %c2, ptr %p1973 %c3 = icmp ule i8 %xor, 1751974 store i1 %c3, ptr %p1975 %c4 = icmp ult i8 %xor, 1751976 store i1 %c4, ptr %p1977 ret void1978}1979 1980define i1 @xor_neg_cond(i32 %a) {1981; CHECK-LABEL: define i1 @xor_neg_cond1982; CHECK-SAME: (i32 [[A:%.*]]) {1983; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[A]], 101984; CHECK-NEXT: [[XOR:%.*]] = xor i1 [[CMP1]], true1985; CHECK-NEXT: br i1 [[XOR]], label [[EXIT:%.*]], label [[GUARD:%.*]]1986; CHECK: guard:1987; CHECK-NEXT: ret i1 true1988; CHECK: exit:1989; CHECK-NEXT: ret i1 false1990;1991 %cmp1 = icmp eq i32 %a, 101992 %xor = xor i1 %cmp1, true1993 br i1 %xor, label %exit, label %guard1994 1995guard:1996 %cmp2 = icmp eq i32 %a, 101997 ret i1 %cmp21998 1999exit:2000 ret i1 false2001}2002 2003define i1 @xor_approx(i32 %a) {2004; CHECK-LABEL: define i1 @xor_approx2005; CHECK-SAME: (i32 [[A:%.*]]) {2006; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i32 [[A]], 22007; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[A]], 52008; CHECK-NEXT: [[CMP3:%.*]] = icmp ugt i32 [[A]], 72009; CHECK-NEXT: [[CMP4:%.*]] = icmp ult i32 [[A]], 92010; CHECK-NEXT: [[AND1:%.*]] = and i1 [[CMP1]], [[CMP2]]2011; CHECK-NEXT: [[AND2:%.*]] = and i1 [[CMP3]], [[CMP4]]2012; CHECK-NEXT: [[OR:%.*]] = or i1 [[AND1]], [[AND2]]2013; CHECK-NEXT: [[XOR:%.*]] = xor i1 [[OR]], true2014; CHECK-NEXT: br i1 [[XOR]], label [[EXIT:%.*]], label [[GUARD:%.*]]2015; CHECK: guard:2016; CHECK-NEXT: [[CMP5:%.*]] = icmp eq i32 [[A]], 62017; CHECK-NEXT: ret i1 [[CMP5]]2018; CHECK: exit:2019; CHECK-NEXT: ret i1 false2020;2021 %cmp1 = icmp ugt i32 %a, 22022 %cmp2 = icmp ult i32 %a, 52023 %cmp3 = icmp ugt i32 %a, 72024 %cmp4 = icmp ult i32 %a, 92025 %and1 = and i1 %cmp1, %cmp22026 %and2 = and i1 %cmp3, %cmp42027 %or = or i1 %and1, %and22028 %xor = xor i1 %or, true2029 br i1 %xor, label %exit, label %guard2030 2031guard:2032 %cmp5 = icmp eq i32 %a, 62033 ret i1 %cmp52034 2035exit:2036 ret i1 false2037}2038 2039define i1 @binop_eval_order(i32 %x) {2040; CHECK-LABEL: define i1 @binop_eval_order2041; CHECK-SAME: (i32 [[X:%.*]]) {2042; CHECK-NEXT: [[A:%.*]] = add nuw nsw i32 [[X]], 12043; CHECK-NEXT: [[B:%.*]] = add nuw nsw i32 [[A]], 12044; CHECK-NEXT: [[C:%.*]] = add nuw nsw i32 [[A]], [[B]]2045; CHECK-NEXT: ret i1 true2046;2047 %a = add nuw nsw i32 %x, 12048 %b = add nuw nsw i32 %a, 12049 %c = add nuw nsw i32 %a, %b2050 %d = icmp ugt i32 %c, 22051 ret i1 %d2052}2053 2054define range(i32 0, 1024) i32 @range_larger(i8 %x) {2055; CHECK-LABEL: define range(i32 0, 256) i32 @range_larger2056; CHECK-SAME: (i8 [[X:%.*]]) {2057; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[X]] to i322058; CHECK-NEXT: ret i32 [[ZEXT]]2059;2060 %zext = zext i8 %x to i322061 ret i32 %zext2062}2063 2064define range(i32 0, 128) i32 @range_smaller(i8 %x) {2065; CHECK-LABEL: define range(i32 0, 128) i32 @range_smaller2066; CHECK-SAME: (i8 [[X:%.*]]) {2067; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[X]] to i322068; CHECK-NEXT: ret i32 [[ZEXT]]2069;2070 %zext = zext i8 %x to i322071 ret i32 %zext2072}2073 2074define range(i32 128, 512) i32 @range_intersect(i8 %x) {2075; CHECK-LABEL: define range(i32 128, 256) i32 @range_intersect2076; CHECK-SAME: (i8 [[X:%.*]]) {2077; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[X]] to i322078; CHECK-NEXT: ret i32 [[ZEXT]]2079;2080 %zext = zext i8 %x to i322081 ret i32 %zext2082}2083 2084define range(i32 512, 1024) i32 @range_non_overlapping(i8 %x) {2085; CHECK-LABEL: define range(i32 512, 1024) i32 @range_non_overlapping2086; CHECK-SAME: (i8 [[X:%.*]]) {2087; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[X]] to i322088; CHECK-NEXT: ret i32 [[ZEXT]]2089;2090 %zext = zext i8 %x to i322091 ret i32 %zext2092}2093 2094declare i32 @llvm.uadd.sat.i32(i32, i32)2095declare i32 @llvm.usub.sat.i32(i32, i32)2096declare i32 @llvm.sadd.sat.i32(i32, i32)2097declare i32 @llvm.ssub.sat.i32(i32, i32)2098declare void @llvm.assume(i1)2099