178 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -passes=jump-threading -S < %s | FileCheck %s3 4declare void @f()5 6define void @test1(i1 %cond, i1 %dummycond) {7; CHECK-LABEL: @test1(8; CHECK-NEXT: br i1 [[COND:%.*]], label [[A:%.*]], label [[B:%.*]]9; CHECK: A:10; CHECK-NEXT: br i1 [[DUMMYCOND:%.*]], label [[REACHABLE:%.*]], label [[DUMMY:%.*]]11; CHECK: B:12; CHECK-NEXT: br i1 [[DUMMYCOND]], label [[REACHABLE]], label [[DUMMY]]13; CHECK: REACHABLE:14; CHECK-NEXT: call void @f()15; CHECK-NEXT: ret void16; CHECK: DUMMY:17; CHECK-NEXT: ret void18;19 br i1 %cond, label %A, label %B20A:21 br i1 %dummycond, label %A2, label %DUMMY22A2:23 %cond.fr = freeze i1 %cond24 br i1 %cond.fr, label %REACHABLE, label %UNREACHABLE25B:26 br i1 %dummycond, label %B2, label %DUMMY27B2:28 %cond.fr2 = freeze i1 %cond29 br i1 %cond.fr2, label %UNREACHABLE, label %REACHABLE30 31REACHABLE:32 call void @f()33 ret void34UNREACHABLE:35 ret void36DUMMY:37 ret void38}39 40define void @test2(i1 %cond, i1 %dummycond) {41; CHECK-LABEL: @test2(42; CHECK-NEXT: [[COND_FR0:%.*]] = freeze i1 [[COND:%.*]]43; CHECK-NEXT: br i1 [[COND_FR0]], label [[A:%.*]], label [[B:%.*]]44; CHECK: A:45; CHECK-NEXT: br i1 [[DUMMYCOND:%.*]], label [[REACHABLE:%.*]], label [[DUMMY:%.*]]46; CHECK: B:47; CHECK-NEXT: br i1 [[DUMMYCOND]], label [[REACHABLE]], label [[DUMMY]]48; CHECK: REACHABLE:49; CHECK-NEXT: call void @f()50; CHECK-NEXT: ret void51; CHECK: DUMMY:52; CHECK-NEXT: ret void53;54 %cond.fr0 = freeze i1 %cond55 br i1 %cond.fr0, label %A, label %B56A:57 br i1 %dummycond, label %A2, label %DUMMY58A2:59 %cond.fr = freeze i1 %cond60 br i1 %cond.fr, label %REACHABLE, label %UNREACHABLE61B:62 br i1 %dummycond, label %B2, label %DUMMY63B2:64 %cond.fr2 = freeze i1 %cond65 br i1 %cond.fr2, label %UNREACHABLE, label %REACHABLE66 67REACHABLE:68 call void @f()69 ret void70UNREACHABLE:71 ret void72DUMMY:73 ret void74}75 76; In this specific example, it is still correct to fold %cond.fr into true.77; This case is unsupported because it is unclear what is the result of78; isImpliedCondition if LHS is poison or undef.79; If isImpliedCondition(poison, any value) is true,80; isImpliedCondition(and true, poison, false) is also true because 'and' propagates poison.81; However, freeze(and true, poison) does not imply false because the former can82; be frozen to true. Therefore, we cannot look through the argument of freeze (%cond.fr0)83; in general under this isImpliedCondition definition.84define void @and_noopt(i32 %x, i1 %cond2, i1 %dummycond) {85; CHECK-LABEL: @and_noopt(86; CHECK-NEXT: [[COND1:%.*]] = icmp slt i32 0, [[X:%.*]]87; CHECK-NEXT: [[COND:%.*]] = and i1 [[COND1]], [[COND2:%.*]]88; CHECK-NEXT: [[COND_FR0:%.*]] = freeze i1 [[COND]]89; CHECK-NEXT: br i1 [[COND_FR0]], label [[A:%.*]], label [[B:%.*]]90; CHECK: A:91; CHECK-NEXT: br i1 [[DUMMYCOND:%.*]], label [[A2:%.*]], label [[DUMMY:%.*]]92; CHECK: A2:93; CHECK-NEXT: [[COND_FR:%.*]] = freeze i1 [[COND1]]94; CHECK-NEXT: br i1 [[COND_FR]], label [[REACHABLE:%.*]], label [[UNREACHABLE:%.*]]95; CHECK: B:96; CHECK-NEXT: br i1 [[DUMMYCOND]], label [[B2:%.*]], label [[DUMMY]]97; CHECK: B2:98; CHECK-NEXT: [[COND_FR2:%.*]] = freeze i1 [[COND1]]99; CHECK-NEXT: br i1 [[COND_FR2]], label [[UNREACHABLE]], label [[REACHABLE]]100; CHECK: REACHABLE:101; CHECK-NEXT: call void @f()102; CHECK-NEXT: ret void103; CHECK: UNREACHABLE:104; CHECK-NEXT: ret void105; CHECK: DUMMY:106; CHECK-NEXT: ret void107;108 %cond1 = icmp slt i32 0, %x109 %cond = and i1 %cond1, %cond2110 %cond.fr0 = freeze i1 %cond111 br i1 %cond.fr0, label %A, label %B112A:113 br i1 %dummycond, label %A2, label %DUMMY114A2:115 %cond.fr = freeze i1 %cond1116 br i1 %cond.fr, label %REACHABLE, label %UNREACHABLE117B:118 br i1 %dummycond, label %B2, label %DUMMY119B2:120 %cond.fr2 = freeze i1 %cond1121 br i1 %cond.fr2, label %UNREACHABLE, label %REACHABLE122 123REACHABLE:124 call void @f()125 ret void126UNREACHABLE:127 ret void128DUMMY:129 ret void130}131 132define void @and(i32 %x, i1 %cond2, i1 %dummycond) {133; CHECK-LABEL: @and(134; CHECK-NEXT: [[COND1:%.*]] = icmp slt i32 0, [[X:%.*]]135; CHECK-NEXT: [[COND:%.*]] = and i1 [[COND1]], [[COND2:%.*]]136; CHECK-NEXT: br i1 [[COND]], label [[A:%.*]], label [[B:%.*]]137; CHECK: A:138; CHECK-NEXT: br i1 [[DUMMYCOND:%.*]], label [[REACHABLE:%.*]], label [[DUMMY:%.*]]139; CHECK: B:140; CHECK-NEXT: br i1 [[DUMMYCOND]], label [[B2:%.*]], label [[DUMMY]]141; CHECK: B2:142; CHECK-NEXT: [[COND_FR2:%.*]] = freeze i1 [[COND1]]143; CHECK-NEXT: br i1 [[COND_FR2]], label [[REACHABLE]], label [[REACHABLE2:%.*]]144; CHECK: REACHABLE:145; CHECK-NEXT: call void @f()146; CHECK-NEXT: ret void147; CHECK: REACHABLE2:148; CHECK-NEXT: call void @f()149; CHECK-NEXT: ret void150; CHECK: DUMMY:151; CHECK-NEXT: ret void152;153 %cond1 = icmp slt i32 0, %x154 %cond = and i1 %cond1, %cond2155 br i1 %cond, label %A, label %B156A:157 br i1 %dummycond, label %A2, label %DUMMY158A2:159 %cond.fr = freeze i1 %cond1160 br i1 %cond.fr, label %REACHABLE, label %UNREACHABLE161B:162 br i1 %dummycond, label %B2, label %DUMMY163B2:164 %cond.fr2 = freeze i1 %cond1165 br i1 %cond.fr2, label %REACHABLE, label %REACHABLE2166 167REACHABLE:168 call void @f()169 ret void170REACHABLE2:171 call void @f()172 ret void173UNREACHABLE:174 ret void175DUMMY:176 ret void177}178