; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt -passes=jump-threading -S < %s | FileCheck %s ; Check the unreachable loop won't cause infinite loop ; in jump-threading when it tries to update the predecessors' ; profile metadata from a phi node. define void @unreachable_single_bb_loop() { ; ; CHECK-LABEL: @unreachable_single_bb_loop( ; CHECK-NEXT: bb: ; CHECK-NEXT: [[TMP:%.*]] = call i32 @a() ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP]], 1 ; CHECK-NEXT: br i1 [[TMP1]], label [[BB8:%.*]], label [[BB8]] ; CHECK: bb2: ; CHECK-NEXT: [[TMP4:%.*]] = icmp ne i32 [[TMP]], 1 ; CHECK-NEXT: switch i1 [[TMP4]], label [[BB2:%.*]] [ ; CHECK-NEXT: i1 false, label [[BB8]] ; CHECK-NEXT: i1 true, label [[BB8]] ; CHECK-NEXT: ] ; CHECK: bb8: ; CHECK-NEXT: ret void ; bb: %tmp = call i32 @a() %tmp1 = icmp eq i32 %tmp, 1 br i1 %tmp1, label %bb5, label %bb8 ; unreachable single bb loop. bb2: ; preds = %bb2 %tmp4 = icmp ne i32 %tmp, 1 switch i1 %tmp4, label %bb2 [ i1 0, label %bb5 i1 1, label %bb8 ] bb5: ; preds = %bb2, %bb %tmp6 = phi i1 [ %tmp1, %bb ], [ false, %bb2 ] br i1 %tmp6, label %bb8, label %bb7, !prof !0 bb7: ; preds = %bb5 br label %bb8 bb8: ; preds = %bb8, %bb7, %bb5, %bb2 ret void } define void @unreachable_multi_bbs_loop() { ; ; CHECK-LABEL: @unreachable_multi_bbs_loop( ; CHECK-NEXT: bb: ; CHECK-NEXT: [[TMP:%.*]] = call i32 @a() ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP]], 1 ; CHECK-NEXT: br i1 [[TMP1]], label [[BB8:%.*]], label [[BB8]] ; CHECK: bb3: ; CHECK-NEXT: br label [[BB2:%.*]] ; CHECK: bb2: ; CHECK-NEXT: [[TMP4:%.*]] = icmp ne i32 [[TMP]], 1 ; CHECK-NEXT: switch i1 [[TMP4]], label [[BB3:%.*]] [ ; CHECK-NEXT: i1 false, label [[BB8]] ; CHECK-NEXT: i1 true, label [[BB8]] ; CHECK-NEXT: ] ; CHECK: bb8: ; CHECK-NEXT: ret void ; bb: %tmp = call i32 @a() %tmp1 = icmp eq i32 %tmp, 1 br i1 %tmp1, label %bb5, label %bb8 ; unreachable two bbs loop. bb3: ; preds = %bb2 br label %bb2 bb2: ; preds = %bb3 %tmp4 = icmp ne i32 %tmp, 1 switch i1 %tmp4, label %bb3 [ i1 0, label %bb5 i1 1, label %bb8 ] bb5: ; preds = %bb2, %bb %tmp6 = phi i1 [ %tmp1, %bb ], [ false, %bb2 ] br i1 %tmp6, label %bb8, label %bb7, !prof !0 bb7: ; preds = %bb5 br label %bb8 bb8: ; preds = %bb8, %bb7, %bb5, %bb2 ret void } declare i32 @a() ; This gets into a state that could cause instruction simplify ; to hang - an insertelement instruction has itself as an operand. define void @PR48362(i1 %arg) { ; ; CHECK-LABEL: @PR48362( ; CHECK-NEXT: cleanup.cont1500: ; CHECK-NEXT: unreachable ; CHECK: if.end1733: ; CHECK-NEXT: [[I82:%.*]] = load i32, ptr undef, align 1 ; CHECK-NEXT: [[TOBOOL1731_NOT:%.*]] = icmp eq i32 [[I82]], 0 ; CHECK-NEXT: br label [[IF_END1733:%.*]] ; cleanup1491: ; preds = %for.body1140 switch i32 0, label %cleanup2343.loopexit4 [ i32 0, label %cleanup.cont1500 i32 128, label %lbl_555.loopexit ] cleanup.cont1500: ; preds = %cleanup1491 unreachable lbl_555.loopexit: ; preds = %cleanup1491 br label %for.body1509 for.body1509: ; preds = %for.inc2340, %lbl_555.loopexit %l_580.sroa.0.0 = phi <4 x i32> [ , %lbl_555.loopexit ], [ %l_580.sroa.0.2, %for.inc2340 ] %p_55.addr.10 = phi i16 [ 0, %lbl_555.loopexit ], [ %p_55.addr.11, %for.inc2340 ] %i82 = load i32, ptr undef, align 1 %tobool1731.not = icmp eq i32 %i82, 0 br i1 %tobool1731.not, label %if.end1733, label %if.then1732 if.then1732: ; preds = %for.body1509 br label %cleanup2329 if.end1733: ; preds = %for.body1509 %tobool1735.not = icmp eq i16 %p_55.addr.10, 0 br i1 %tobool1735.not, label %if.then1736, label %if.else1904 if.then1736: ; preds = %if.end1733 br label %cleanup2329 if.else1904: ; preds = %if.end1733 br label %for.body1911 for.body1911: ; preds = %if.else1904 %l_580.sroa.0.4.vec.extract683 = extractelement <4 x i32> %l_580.sroa.0.0, i32 2 %xor2107 = xor i32 undef, %l_580.sroa.0.4.vec.extract683 br label %land.end2173 land.end2173: ; preds = %for.body1911 br i1 %arg, label %if.end2178, label %cleanup2297 if.end2178: ; preds = %land.end2173 %l_580.sroa.0.2.vec.insert = insertelement <4 x i32> %l_580.sroa.0.0, i32 undef, i32 1 br label %cleanup2297 cleanup2297: ; preds = %if.end2178, %land.end2173 %l_580.sroa.0.1 = phi <4 x i32> [ %l_580.sroa.0.2.vec.insert, %if.end2178 ], [ %l_580.sroa.0.0, %land.end2173 ] br label %cleanup2329 cleanup2329: ; preds = %cleanup2297, %if.then1736, %if.then1732 %l_580.sroa.0.2 = phi <4 x i32> [ %l_580.sroa.0.0, %if.then1736 ], [ %l_580.sroa.0.1, %cleanup2297 ], [ %l_580.sroa.0.0, %if.then1732 ] %cleanup.dest.slot.11 = phi i32 [ 0, %if.then1736 ], [ undef, %cleanup2297 ], [ 129, %if.then1732 ] %p_55.addr.11 = phi i16 [ %p_55.addr.10, %if.then1736 ], [ undef, %cleanup2297 ], [ %p_55.addr.10, %if.then1732 ] switch i32 %cleanup.dest.slot.11, label %cleanup2343.loopexit [ i32 0, label %cleanup.cont2339 i32 129, label %crit_edge114 ] cleanup.cont2339: ; preds = %cleanup2329 br label %for.inc2340 for.inc2340: ; preds = %cleanup.cont2339 br i1 %arg, label %for.body1509, label %crit_edge115 crit_edge114: ; preds = %cleanup2329 unreachable crit_edge115: ; preds = %for.inc2340 unreachable cleanup2343.loopexit: ; preds = %cleanup2329 unreachable cleanup2343.loopexit4: ; preds = %cleanup1491 unreachable } ; This segfaults due to recursion in %C4. Reason: %L6 is identified to be a ; "partially redundant load" and is replaced by a PHI node. The PHI node is then ; simplified to be constant and is removed. This leads to %L6 being replaced by ; %C4, which makes %C4 invalid since it uses %L6. ; The test case has been generated by the AMD Fuzzing project and simplified ; manually and by llvm-reduce. define i32 @constant_phi_leads_to_self_reference(ptr %ptr) { ; CHECK-LABEL: @constant_phi_leads_to_self_reference( ; CHECK-NEXT: [[A9:%.*]] = alloca i1, align 1 ; CHECK-NEXT: br label [[F6:%.*]] ; CHECK: T3: ; CHECK-NEXT: br label [[BB5:%.*]] ; CHECK: BB5: ; CHECK-NEXT: [[L10:%.*]] = load i1, ptr [[A9]], align 1 ; CHECK-NEXT: br i1 [[L10]], label [[BB6:%.*]], label [[F6]] ; CHECK: BB6: ; CHECK-NEXT: [[LGV3:%.*]] = load i1, ptr [[PTR:%.*]], align 1 ; CHECK-NEXT: [[C4:%.*]] = icmp sle i1 [[C4]], true ; CHECK-NEXT: store i1 [[C4]], ptr [[PTR]], align 1 ; CHECK-NEXT: br i1 [[C4]], label [[F6]], label [[T3:%.*]] ; CHECK: F6: ; CHECK-NEXT: ret i32 0 ; CHECK: F7: ; CHECK-NEXT: br label [[BB5]] ; %A9 = alloca i1, align 1 br i1 false, label %BB4, label %F6 BB4: ; preds = %0 br i1 false, label %F6, label %F1 F1: ; preds = %BB4 br i1 false, label %T4, label %T3 T3: ; preds = %T4, %BB6, %F1 %L6 = load i1, ptr %ptr, align 1 br label %BB5 BB5: ; preds = %F7, %T3 %L10 = load i1, ptr %A9, align 1 br i1 %L10, label %BB6, label %F6 BB6: ; preds = %BB5 %LGV3 = load i1, ptr %ptr, align 1 %C4 = icmp sle i1 %L6, true store i1 %C4, ptr %ptr, align 1 br i1 %L6, label %F6, label %T3 T4: ; preds = %F1 br label %T3 F6: ; preds = %BB6, %BB5, %BB4, %0 ret i32 0 F7: ; No predecessors! br label %BB5 } ; Same as above, but with multiple icmps referencing the same PHI node. define i32 @recursive_icmp_mult(ptr %ptr) { ; CHECK-LABEL: @recursive_icmp_mult( ; CHECK-NEXT: [[A9:%.*]] = alloca i1, align 1 ; CHECK-NEXT: br label [[F6:%.*]] ; CHECK: T3: ; CHECK-NEXT: br label [[BB5:%.*]] ; CHECK: BB5: ; CHECK-NEXT: [[L10:%.*]] = load i1, ptr [[A9]], align 1 ; CHECK-NEXT: br i1 [[L10]], label [[BB6:%.*]], label [[F6]] ; CHECK: BB6: ; CHECK-NEXT: [[LGV3:%.*]] = load i1, ptr [[PTR:%.*]], align 1 ; CHECK-NEXT: [[C4:%.*]] = icmp sle i1 [[C6:%.*]], true ; CHECK-NEXT: [[C5:%.*]] = icmp sle i1 [[C6]], false ; CHECK-NEXT: [[C6]] = icmp sle i1 [[C4]], [[C5]] ; CHECK-NEXT: store i1 [[C6]], ptr [[PTR]], align 1 ; CHECK-NEXT: br i1 [[C6]], label [[F6]], label [[T3:%.*]] ; CHECK: F6: ; CHECK-NEXT: ret i32 0 ; CHECK: F7: ; CHECK-NEXT: br label [[BB5]] ; %A9 = alloca i1, align 1 br i1 false, label %BB4, label %F6 BB4: ; preds = %0 br i1 false, label %F6, label %F1 F1: ; preds = %BB4 br i1 false, label %T4, label %T3 T3: ; preds = %T4, %BB6, %F1 %L6 = load i1, ptr %ptr, align 1 br label %BB5 BB5: ; preds = %F7, %T3 %L10 = load i1, ptr %A9, align 1 br i1 %L10, label %BB6, label %F6 BB6: ; preds = %BB5 %LGV3 = load i1, ptr %ptr, align 1 %C4 = icmp sle i1 %L6, true %C5 = icmp sle i1 %L6, false %C6 = icmp sle i1 %C4, %C5 store i1 %C6, ptr %ptr, align 1 br i1 %L6, label %F6, label %T3 T4: ; preds = %F1 br label %T3 F6: ; preds = %BB6, %BB5, %BB4, %0 ret i32 0 F7: ; No predecessors! br label %BB5 } !0 = !{!"branch_weights", i32 2146410443, i32 1073205}