Skip to content

Conversation

@kper
Copy link
Contributor

@kper kper commented Jun 3, 2025

If BB and Succ have no phis then then Pred should not be directed to Succ directly. My assumption is that otherwise BB will be merged into Succ directly means that another optimisation will eliminate BB.

Closes #142242

@llvmbot
Copy link
Member

llvmbot commented Jun 3, 2025

@llvm/pr-subscribers-llvm-transforms
@llvm/pr-subscribers-backend-aarch64

@llvm/pr-subscribers-backend-hexagon

Author: None (kper)

Changes

If BB and Succ have no phis then then Pred should not be directed to Succ directly. My assumption is that otherwise BB will be merged into Succ directly means that another optimisation will eliminate BB.

Closes #142242


Full diff: https://github.com/llvm/llvm-project/pull/142582.diff

9 Files Affected:

  • (modified) llvm/lib/Transforms/Utils/Local.cpp (+1-1)
  • (modified) llvm/test/CodeGen/AArch64/and-sink.ll (+4-5)
  • (modified) llvm/test/CodeGen/AArch64/combine-comparisons-by-cse.ll (+49-72)
  • (modified) llvm/test/CodeGen/AArch64/wineh-catchret-label-generation.ll (+26-21)
  • (modified) llvm/test/CodeGen/Hexagon/vect/zext-v4i1.ll (+5-13)
  • (modified) llvm/test/Transforms/JumpThreading/pr79175.ll (+4-4)
  • (modified) llvm/test/Transforms/JumpThreading/preserving-debugloc-fold-select.ll (+1-1)
  • (modified) llvm/test/Transforms/JumpThreading/thread-prob-7.ll (+4-4)
  • (added) llvm/test/Transforms/SimplifyCFG/pr142242.ll (+32)
diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp
index a0618726ac0ac..f73bf219e1268 100644
--- a/llvm/lib/Transforms/Utils/Local.cpp
+++ b/llvm/lib/Transforms/Utils/Local.cpp
@@ -1021,7 +1021,7 @@ CanRedirectPredsOfEmptyBBToSucc(BasicBlock *BB, BasicBlock *Succ,
                                 BasicBlock *&CommonPred) {
 
   // There must be phis in BB, otherwise BB will be merged into Succ directly
-  if (BB->phis().empty() || Succ->phis().empty())
+  if (BB->phis().empty() && Succ->phis().empty())
     return false;
 
   // BB must have predecessors not shared that can be redirected to Succ
diff --git a/llvm/test/CodeGen/AArch64/and-sink.ll b/llvm/test/CodeGen/AArch64/and-sink.ll
index c84310629e5fd..277091a65e862 100644
--- a/llvm/test/CodeGen/AArch64/and-sink.ll
+++ b/llvm/test/CodeGen/AArch64/and-sink.ll
@@ -11,15 +11,14 @@
 define dso_local i32 @and_sink1(i32 %a, i1 %c) {
 ; CHECK-LABEL: and_sink1:
 ; CHECK:       // %bb.0:
-; CHECK-NEXT:    tbz w1, #0, .LBB0_3
+; CHECK-NEXT:    tbz w1, #0, .LBB0_2
 ; CHECK-NEXT:  // %bb.1: // %bb0
+; CHECK-NEXT:    tst w0, #0x4
 ; CHECK-NEXT:    adrp x8, A
+; CHECK-NEXT:    cset w0, eq
 ; CHECK-NEXT:    str wzr, [x8, :lo12:A]
-; CHECK-NEXT:    tbnz w0, #2, .LBB0_3
-; CHECK-NEXT:  // %bb.2:
-; CHECK-NEXT:    mov w0, #1 // =0x1
 ; CHECK-NEXT:    ret
-; CHECK-NEXT:  .LBB0_3: // %bb2
+; CHECK-NEXT:  .LBB0_2:
 ; CHECK-NEXT:    mov w0, wzr
 ; CHECK-NEXT:    ret
 
diff --git a/llvm/test/CodeGen/AArch64/combine-comparisons-by-cse.ll b/llvm/test/CodeGen/AArch64/combine-comparisons-by-cse.ll
index 6449c3e11d667..4a91359fe138c 100644
--- a/llvm/test/CodeGen/AArch64/combine-comparisons-by-cse.ll
+++ b/llvm/test/CodeGen/AArch64/combine-comparisons-by-cse.ll
@@ -13,10 +13,10 @@ define i32 @combine_gt_ge_10() #0 {
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    adrp x8, :got:a
 ; CHECK-NEXT:    ldr x8, [x8, :got_lo12:a]
-; CHECK-NEXT:    ldr w8, [x8]
-; CHECK-NEXT:    cmp w8, #10
+; CHECK-NEXT:    ldr w9, [x8]
 ; CHECK-NEXT:    adrp x8, :got:b
 ; CHECK-NEXT:    ldr x8, [x8, :got_lo12:b]
+; CHECK-NEXT:    cmp w9, #10
 ; CHECK-NEXT:    b.le .LBB0_3
 ; CHECK-NEXT:  // %bb.1: // %land.lhs.true
 ; CHECK-NEXT:    adrp x9, :got:c
@@ -29,18 +29,17 @@ define i32 @combine_gt_ge_10() #0 {
 ; CHECK-NEXT:    mov w0, #1 // =0x1
 ; CHECK-NEXT:    ret
 ; CHECK-NEXT:  .LBB0_3: // %lor.lhs.false
-; CHECK-NEXT:    b.lt .LBB0_6
+; CHECK-NEXT:    cmp w9, #10
+; CHECK-NEXT:    b.lt .LBB0_5
 ; CHECK-NEXT:  .LBB0_4: // %land.lhs.true3
 ; CHECK-NEXT:    adrp x9, :got:d
 ; CHECK-NEXT:    ldr x9, [x9, :got_lo12:d]
 ; CHECK-NEXT:    ldr w8, [x8]
 ; CHECK-NEXT:    ldr w9, [x9]
 ; CHECK-NEXT:    cmp w8, w9
-; CHECK-NEXT:    b.ne .LBB0_6
-; CHECK-NEXT:  // %bb.5:
-; CHECK-NEXT:    mov w0, #1 // =0x1
+; CHECK-NEXT:    cset w0, eq
 ; CHECK-NEXT:    ret
-; CHECK-NEXT:  .LBB0_6: // %if.end
+; CHECK-NEXT:  .LBB0_5:
 ; CHECK-NEXT:    mov w0, wzr
 ; CHECK-NEXT:    ret
 entry:
@@ -145,10 +144,10 @@ define i32 @combine_lt_ge_5() #0 {
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    adrp x8, :got:a
 ; CHECK-NEXT:    ldr x8, [x8, :got_lo12:a]
-; CHECK-NEXT:    ldr w8, [x8]
-; CHECK-NEXT:    cmp w8, #5
+; CHECK-NEXT:    ldr w9, [x8]
 ; CHECK-NEXT:    adrp x8, :got:b
 ; CHECK-NEXT:    ldr x8, [x8, :got_lo12:b]
+; CHECK-NEXT:    cmp w9, #5
 ; CHECK-NEXT:    b.ge .LBB2_3
 ; CHECK-NEXT:  // %bb.1: // %land.lhs.true
 ; CHECK-NEXT:    adrp x9, :got:c
@@ -161,18 +160,17 @@ define i32 @combine_lt_ge_5() #0 {
 ; CHECK-NEXT:    mov w0, #1 // =0x1
 ; CHECK-NEXT:    ret
 ; CHECK-NEXT:  .LBB2_3: // %lor.lhs.false
-; CHECK-NEXT:    b.gt .LBB2_6
+; CHECK-NEXT:    cmp w9, #5
+; CHECK-NEXT:    b.gt .LBB2_5
 ; CHECK-NEXT:  .LBB2_4: // %land.lhs.true3
 ; CHECK-NEXT:    adrp x9, :got:d
 ; CHECK-NEXT:    ldr x9, [x9, :got_lo12:d]
 ; CHECK-NEXT:    ldr w8, [x8]
 ; CHECK-NEXT:    ldr w9, [x9]
 ; CHECK-NEXT:    cmp w8, w9
-; CHECK-NEXT:    b.ne .LBB2_6
-; CHECK-NEXT:  // %bb.5:
-; CHECK-NEXT:    mov w0, #1 // =0x1
+; CHECK-NEXT:    cset w0, eq
 ; CHECK-NEXT:    ret
-; CHECK-NEXT:  .LBB2_6: // %if.end
+; CHECK-NEXT:  .LBB2_5:
 ; CHECK-NEXT:    mov w0, wzr
 ; CHECK-NEXT:    ret
 entry:
@@ -499,24 +497,17 @@ define i32 @do_nothing_if_resultant_opcodes_would_differ() #0 {
 ; CHECK-NEXT:  // %bb.3: // %while.cond.while.end_crit_edge
 ; CHECK-NEXT:    ldr w8, [x19]
 ; CHECK-NEXT:  .LBB7_4: // %while.end
-; CHECK-NEXT:    cmp w8, #1
-; CHECK-NEXT:    b.gt .LBB7_7
-; CHECK-NEXT:  // %bb.5: // %land.lhs.true
-; CHECK-NEXT:    adrp x8, :got:b
-; CHECK-NEXT:    adrp x9, :got:d
-; CHECK-NEXT:    ldr x8, [x8, :got_lo12:b]
-; CHECK-NEXT:    ldr x9, [x9, :got_lo12:d]
-; CHECK-NEXT:    ldr w8, [x8]
-; CHECK-NEXT:    ldr w9, [x9]
-; CHECK-NEXT:    cmp w8, w9
-; CHECK-NEXT:    b.ne .LBB7_7
-; CHECK-NEXT:  // %bb.6:
-; CHECK-NEXT:    mov w0, #123 // =0x7b
-; CHECK-NEXT:    b .LBB7_8
-; CHECK-NEXT:  .LBB7_7: // %if.end
-; CHECK-NEXT:    mov w0, wzr
-; CHECK-NEXT:  .LBB7_8: // %return
+; CHECK-NEXT:    adrp x9, :got:b
+; CHECK-NEXT:    adrp x10, :got:d
+; CHECK-NEXT:    ldr x9, [x9, :got_lo12:b]
+; CHECK-NEXT:    ldr x10, [x10, :got_lo12:d]
 ; CHECK-NEXT:    ldp x20, x19, [sp, #16] // 16-byte Folded Reload
+; CHECK-NEXT:    ldr w9, [x9]
+; CHECK-NEXT:    ldr w10, [x10]
+; CHECK-NEXT:    cmp w9, w10
+; CHECK-NEXT:    ccmp w8, #2, #0, eq
+; CHECK-NEXT:    mov w8, #123 // =0x7b
+; CHECK-NEXT:    csel w0, w8, wzr, lt
 ; CHECK-NEXT:    ldr x30, [sp], #32 // 8-byte Folded Reload
 ; CHECK-NEXT:    .cfi_def_cfa_offset 0
 ; CHECK-NEXT:    .cfi_restore w19
@@ -564,52 +555,41 @@ return:                                           ; preds = %if.end, %land.lhs.t
 define i32 @do_nothing_if_compares_can_not_be_adjusted_to_each_other() #0 {
 ; CHECK-LABEL: do_nothing_if_compares_can_not_be_adjusted_to_each_other:
 ; CHECK:       // %bb.0: // %entry
-; CHECK-NEXT:    stp x30, x19, [sp, #-16]! // 16-byte Folded Spill
-; CHECK-NEXT:    .cfi_def_cfa_offset 16
-; CHECK-NEXT:    .cfi_offset w19, -8
-; CHECK-NEXT:    .cfi_offset w30, -16
-; CHECK-NEXT:    .cfi_remember_state
 ; CHECK-NEXT:    adrp x8, :got:a
 ; CHECK-NEXT:    ldr x8, [x8, :got_lo12:a]
 ; CHECK-NEXT:    ldr w8, [x8]
 ; CHECK-NEXT:    cmp w8, #0
-; CHECK-NEXT:    b.gt .LBB8_3
+; CHECK-NEXT:    b.gt .LBB8_4
 ; CHECK-NEXT:  // %bb.1: // %while.body.preheader
+; CHECK-NEXT:    stp x30, x19, [sp, #-16]! // 16-byte Folded Spill
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    .cfi_offset w19, -8
+; CHECK-NEXT:    .cfi_offset w30, -16
 ; CHECK-NEXT:    sub w19, w8, #1
 ; CHECK-NEXT:  .LBB8_2: // %while.body
 ; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
 ; CHECK-NEXT:    bl do_something
 ; CHECK-NEXT:    adds w19, w19, #1
 ; CHECK-NEXT:    b.mi .LBB8_2
-; CHECK-NEXT:  .LBB8_3: // %while.end
-; CHECK-NEXT:    adrp x8, :got:c
-; CHECK-NEXT:    ldr x8, [x8, :got_lo12:c]
-; CHECK-NEXT:    ldr w8, [x8]
-; CHECK-NEXT:    cmn w8, #2
-; CHECK-NEXT:    b.lt .LBB8_6
-; CHECK-NEXT:  // %bb.4: // %land.lhs.true
+; CHECK-NEXT:  // %bb.3:
+; CHECK-NEXT:    ldp x30, x19, [sp], #16 // 16-byte Folded Reload
+; CHECK-NEXT:    .cfi_def_cfa_offset 0
+; CHECK-NEXT:    .cfi_restore w19
+; CHECK-NEXT:    .cfi_restore w30
+; CHECK-NEXT:  .LBB8_4: // %while.end
 ; CHECK-NEXT:    adrp x8, :got:b
 ; CHECK-NEXT:    adrp x9, :got:d
+; CHECK-NEXT:    adrp x10, :got:c
 ; CHECK-NEXT:    ldr x8, [x8, :got_lo12:b]
 ; CHECK-NEXT:    ldr x9, [x9, :got_lo12:d]
+; CHECK-NEXT:    ldr x10, [x10, :got_lo12:c]
 ; CHECK-NEXT:    ldr w8, [x8]
 ; CHECK-NEXT:    ldr w9, [x9]
+; CHECK-NEXT:    ldr w10, [x10]
 ; CHECK-NEXT:    cmp w8, w9
-; CHECK-NEXT:    b.ne .LBB8_6
-; CHECK-NEXT:  // %bb.5:
-; CHECK-NEXT:    mov w0, #123 // =0x7b
-; CHECK-NEXT:    ldp x30, x19, [sp], #16 // 16-byte Folded Reload
-; CHECK-NEXT:    .cfi_def_cfa_offset 0
-; CHECK-NEXT:    .cfi_restore w19
-; CHECK-NEXT:    .cfi_restore w30
-; CHECK-NEXT:    ret
-; CHECK-NEXT:  .LBB8_6: // %if.end
-; CHECK-NEXT:    .cfi_restore_state
-; CHECK-NEXT:    mov w0, wzr
-; CHECK-NEXT:    ldp x30, x19, [sp], #16 // 16-byte Folded Reload
-; CHECK-NEXT:    .cfi_def_cfa_offset 0
-; CHECK-NEXT:    .cfi_restore w19
-; CHECK-NEXT:    .cfi_restore w30
+; CHECK-NEXT:    mov w8, #123 // =0x7b
+; CHECK-NEXT:    ccmn w10, #3, #4, eq
+; CHECK-NEXT:    csel w0, w8, wzr, gt
 ; CHECK-NEXT:    ret
 entry:
   %0 = load i32, ptr @a, align 4
@@ -782,12 +762,14 @@ define i32 @combine_gt_ge_sel(i64 %v, ptr %p) #0 {
 ; CHECK-NEXT:    cmp w8, #0
 ; CHECK-NEXT:    csel x9, x0, xzr, gt
 ; CHECK-NEXT:    str x9, [x1]
-; CHECK-NEXT:    b.le .LBB11_2
+; CHECK-NEXT:    b.le .LBB11_3
 ; CHECK-NEXT:  // %bb.1: // %lor.lhs.false
 ; CHECK-NEXT:    cmp w8, #2
-; CHECK-NEXT:    b.ge .LBB11_4
-; CHECK-NEXT:    b .LBB11_6
-; CHECK-NEXT:  .LBB11_2: // %land.lhs.true
+; CHECK-NEXT:    b.ge .LBB11_5
+; CHECK-NEXT:  // %bb.2:
+; CHECK-NEXT:    mov w0, wzr
+; CHECK-NEXT:    ret
+; CHECK-NEXT:  .LBB11_3: // %land.lhs.true
 ; CHECK-NEXT:    adrp x8, :got:b
 ; CHECK-NEXT:    adrp x9, :got:c
 ; CHECK-NEXT:    ldr x8, [x8, :got_lo12:b]
@@ -795,11 +777,11 @@ define i32 @combine_gt_ge_sel(i64 %v, ptr %p) #0 {
 ; CHECK-NEXT:    ldr w8, [x8]
 ; CHECK-NEXT:    ldr w9, [x9]
 ; CHECK-NEXT:    cmp w8, w9
-; CHECK-NEXT:    b.ne .LBB11_4
-; CHECK-NEXT:  // %bb.3:
+; CHECK-NEXT:    b.ne .LBB11_5
+; CHECK-NEXT:  // %bb.4:
 ; CHECK-NEXT:    mov w0, #1 // =0x1
 ; CHECK-NEXT:    ret
-; CHECK-NEXT:  .LBB11_4: // %land.lhs.true3
+; CHECK-NEXT:  .LBB11_5: // %land.lhs.true3
 ; CHECK-NEXT:    adrp x8, :got:b
 ; CHECK-NEXT:    adrp x9, :got:d
 ; CHECK-NEXT:    ldr x8, [x8, :got_lo12:b]
@@ -807,12 +789,7 @@ define i32 @combine_gt_ge_sel(i64 %v, ptr %p) #0 {
 ; CHECK-NEXT:    ldr w8, [x8]
 ; CHECK-NEXT:    ldr w9, [x9]
 ; CHECK-NEXT:    cmp w8, w9
-; CHECK-NEXT:    b.ne .LBB11_6
-; CHECK-NEXT:  // %bb.5:
-; CHECK-NEXT:    mov w0, #1 // =0x1
-; CHECK-NEXT:    ret
-; CHECK-NEXT:  .LBB11_6: // %if.end
-; CHECK-NEXT:    mov w0, wzr
+; CHECK-NEXT:    cset w0, eq
 ; CHECK-NEXT:    ret
 entry:
   %0 = load i32, ptr @a, align 4
diff --git a/llvm/test/CodeGen/AArch64/wineh-catchret-label-generation.ll b/llvm/test/CodeGen/AArch64/wineh-catchret-label-generation.ll
index 3f7df585c52b4..3a36f3128239f 100644
--- a/llvm/test/CodeGen/AArch64/wineh-catchret-label-generation.ll
+++ b/llvm/test/CodeGen/AArch64/wineh-catchret-label-generation.ll
@@ -11,26 +11,30 @@ define fastcc ptr @test_function(i1 %0, ptr %_Fmtfl.i.i, i1 %1) personality ptr
 ; CHECK-NEXT:  .seh_proc test_function
 ; CHECK-NEXT:    .seh_handler __CxxFrameHandler3, @unwind, @except
 ; CHECK-NEXT:  // %bb.0: // %entry
-; CHECK-NEXT:    stp x29, x30, [sp, #-32]! // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_fplr_x 32
-; CHECK-NEXT:    mov x29, sp
-; CHECK-NEXT:    .seh_set_fp
+; CHECK-NEXT:    sub sp, sp, #48
+; CHECK-NEXT:    .seh_stackalloc 48
+; CHECK-NEXT:    stp x29, x30, [sp, #16] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_fplr 16
+; CHECK-NEXT:    add x29, sp, #16
+; CHECK-NEXT:    .seh_add_fp 16
 ; CHECK-NEXT:    .seh_endprologue
 ; CHECK-NEXT:    mov x3, #-2 // =0xfffffffffffffffe
 ; CHECK-NEXT:    stur x3, [x29, #16]
-; CHECK-NEXT:    tbz w0, #0, .LBB0_3
+; CHECK-NEXT:    tbz w0, #0, .LBB0_2
 ; CHECK-NEXT:  // %bb.1: // %invoke.cont.i124
-; CHECK-NEXT:    mov x0, x1
-; CHECK-NEXT:    b .LBB0_4
-; CHECK-NEXT:  .LBB0_2: // Block address taken
-; CHECK-NEXT:    // %some-block
-; CHECK-NEXT:  $ehgcr_0_2:
-; CHECK-NEXT:  .LBB0_3: // %left-block526
-; CHECK-NEXT:    mov x0, xzr
-; CHECK-NEXT:  .LBB0_4: // %common.ret1
+; CHECK-NEXT:    stur x1, [x29, #-8] // 8-byte Folded Spill
+; CHECK-NEXT:    b .LBB0_3
+; CHECK-NEXT:  .LBB0_2: // %left-block526
+; CHECK-NEXT:    stur xzr, [x29, #-8] // 8-byte Folded Spill
+; CHECK-NEXT:  .LBB0_3: // Block address taken
+; CHECK-NEXT:    // %common.ret1
+; CHECK-NEXT:  $ehgcr_0_3:
+; CHECK-NEXT:    ldur x0, [x29, #-8] // 8-byte Folded Reload
 ; CHECK-NEXT:    .seh_startepilogue
-; CHECK-NEXT:    ldp x29, x30, [sp], #32 // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_fplr_x 32
+; CHECK-NEXT:    ldp x29, x30, [sp, #16] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_fplr 16
+; CHECK-NEXT:    add sp, sp, #48
+; CHECK-NEXT:    .seh_stackalloc 48
 ; CHECK-NEXT:    .seh_endepilogue
 ; CHECK-NEXT:    ret
 ; CHECK-NEXT:    .seh_endfunclet
@@ -38,20 +42,21 @@ define fastcc ptr @test_function(i1 %0, ptr %_Fmtfl.i.i, i1 %1) personality ptr
 ; CHECK-NEXT:    .word $cppxdata$test_function@IMGREL
 ; CHECK-NEXT:    .text
 ; CHECK-NEXT:    .seh_endproc
-; CHECK-NEXT:    .def "?catch$5@?0?test_function@4HA";
+; CHECK-NEXT:    .def "?catch$4@?0?test_function@4HA";
 ; CHECK-NEXT:    .scl 3;
 ; CHECK-NEXT:    .type 32;
 ; CHECK-NEXT:    .endef
 ; CHECK-NEXT:    .p2align 2
-; CHECK-NEXT:  "?catch$5@?0?test_function@4HA":
-; CHECK-NEXT:  .seh_proc "?catch$5@?0?test_function@4HA"
+; CHECK-NEXT:  "?catch$4@?0?test_function@4HA":
+; CHECK-NEXT:  .seh_proc "?catch$4@?0?test_function@4HA"
 ; CHECK-NEXT:    .seh_handler __CxxFrameHandler3, @unwind, @except
-; CHECK-NEXT:  .LBB0_5: // %catch.i
+; CHECK-NEXT:  .LBB0_4: // %catch.i
 ; CHECK-NEXT:    stp x29, x30, [sp, #-16]! // 16-byte Folded Spill
 ; CHECK-NEXT:    .seh_save_fplr_x 16
 ; CHECK-NEXT:    .seh_endprologue
-; CHECK-NEXT:    adrp x0, .LBB0_2
-; CHECK-NEXT:    add x0, x0, .LBB0_2
+; CHECK-NEXT:    stur xzr, [x29, #-8] // 8-byte Folded Spill
+; CHECK-NEXT:    adrp x0, .LBB0_3
+; CHECK-NEXT:    add x0, x0, .LBB0_3
 ; CHECK-NEXT:    .seh_startepilogue
 ; CHECK-NEXT:    ldp x29, x30, [sp], #16 // 16-byte Folded Reload
 ; CHECK-NEXT:    .seh_save_fplr_x 16
diff --git a/llvm/test/CodeGen/Hexagon/vect/zext-v4i1.ll b/llvm/test/CodeGen/Hexagon/vect/zext-v4i1.ll
index 559bb68741e12..e75a8e99161c7 100644
--- a/llvm/test/CodeGen/Hexagon/vect/zext-v4i1.ll
+++ b/llvm/test/CodeGen/Hexagon/vect/zext-v4i1.ll
@@ -10,12 +10,13 @@ define i32 @fred(ptr %a0) #0 {
 ; CHECK-LABEL: fred:
 ; CHECK:       // %bb.0: // %b0
 ; CHECK-NEXT:    {
-; CHECK-NEXT:     if (p0) jump:nt .LBB0_2
+; CHECK-NEXT:     r1:0 = combine(r0,#0)
+; CHECK-NEXT:     if (p0) jumpr r31
 ; CHECK-NEXT:    }
-; CHECK-NEXT:  // %bb.1: // %b2
+; CHECK-NEXT:  .LBB0_1: // %b2
 ; CHECK-NEXT:    {
 ; CHECK-NEXT:     r3:2 = combine(#0,#0)
-; CHECK-NEXT:     r1:0 = memd(r0+#0)
+; CHECK-NEXT:     r1:0 = memd(r1+#0)
 ; CHECK-NEXT:    }
 ; CHECK-NEXT:    {
 ; CHECK-NEXT:     p0 = vcmph.eq(r1:0,r3:2)
@@ -27,16 +28,7 @@ define i32 @fred(ptr %a0) #0 {
 ; CHECK-NEXT:     r0 = and(r0,#1)
 ; CHECK-NEXT:    }
 ; CHECK-NEXT:    {
-; CHECK-NEXT:     p0 = cmp.eq(r0,#11)
-; CHECK-NEXT:     r0 = #1
-; CHECK-NEXT:    }
-; CHECK-NEXT:    {
-; CHECK-NEXT:     if (p0) r0 = #0
-; CHECK-NEXT:     jumpr r31
-; CHECK-NEXT:    }
-; CHECK-NEXT:  .LBB0_2: // %b14
-; CHECK-NEXT:    {
-; CHECK-NEXT:     r0 = #0
+; CHECK-NEXT:     r0 = !cmp.eq(r0,#11)
 ; CHECK-NEXT:     jumpr r31
 ; CHECK-NEXT:    }
 b0:
diff --git a/llvm/test/Transforms/JumpThreading/pr79175.ll b/llvm/test/Transforms/JumpThreading/pr79175.ll
index 2c7ee0770cdc7..cce30ce079999 100644
--- a/llvm/test/Transforms/JumpThreading/pr79175.ll
+++ b/llvm/test/Transforms/JumpThreading/pr79175.ll
@@ -17,11 +17,11 @@ define i32 @test(i64 %idx, i32 %val) {
 ; CHECK:       cond.end:
 ; CHECK-NEXT:    [[CMP_I:%.*]] = icmp sgt i32 [[VAL]], 0
 ; CHECK-NEXT:    [[COND_FR:%.*]] = freeze i1 [[CMP_I]]
-; CHECK-NEXT:    br i1 [[COND_FR]], label [[COND_END_THREAD]], label [[TMP0:%.*]]
-; CHECK:       cond.end.thread:
-; CHECK-NEXT:    br label [[TMP0]]
+; CHECK-NEXT:    br i1 [[COND_FR]], label [[TMP0:%.*]], label [[COND_END_THREAD]]
 ; CHECK:       0:
-; CHECK-NEXT:    [[TMP1:%.*]] = phi i32 [ 0, [[COND_END_THREAD]] ], [ [[VAL]], [[COND_END]] ]
+; CHECK-NEXT:    br label [[COND_END_THREAD]]
+; CHECK:       cond.end.thread:
+; CHECK-NEXT:    [[TMP1:%.*]] = phi i32 [ [[VAL]], [[COND_END]] ], [ 0, [[TMP0]] ], [ 0, [[FOR_BODY]] ]
 ; CHECK-NEXT:    [[F_IDX:%.*]] = getelementptr inbounds i32, ptr @f, i64 [[IDX]]
 ; CHECK-NEXT:    store i32 [[TMP1]], ptr [[F_IDX]], align 4
 ; CHECK-NEXT:    [[F_RELOAD:%.*]] = load i32, ptr @f, align 4
diff --git a/llvm/test/Transforms/JumpThreading/preserving-debugloc-fold-select.ll b/llvm/test/Transforms/JumpThreading/preserving-debugloc-fold-select.ll
index 8fdec7210980c..118ad0f21212d 100644
--- a/llvm/test/Transforms/JumpThreading/preserving-debugloc-fold-select.ll
+++ b/llvm/test/Transforms/JumpThreading/preserving-debugloc-fold-select.ll
@@ -4,7 +4,7 @@
 ; which replaces the select instruction in .exit block.
 
 define i32 @unfold3(i32 %u, i32 %v, i32 %w, i32 %x, i32 %y, i32 %z, i32 %j) !dbg !5 {
-; CHECK:       .exit.thread4:
+; CHECK:       .exit.thread:
 ; CHECK-NEXT:    [[TMP0:%.*]] = phi i32 {{.*}}, !dbg [[DBG29:![0-9]+]]
 ; CHECK-NEXT:    ret i32 [[TMP0]], !dbg [[DBG30:![0-9]+]]
 ;
diff --git a/llvm/test/Transforms/JumpThreading/thread-prob-7.ll b/llvm/test/Transforms/JumpThreading/thread-prob-7.ll
index 8c9d89871d00b..bb77f651cba69 100644
--- a/llvm/test/Transforms/JumpThreading/thread-prob-7.ll
+++ b/llvm/test/Transforms/JumpThreading/thread-prob-7.ll
@@ -11,18 +11,18 @@ define i32 @func0(i32 %a0, i32 %a1) !prof !0 {
 ; CHECK-NEXT:    br i1 [[CMP0]], label [[BB_JOIN:%.*]], label [[TEST2:%.*]], !prof [[PROF1:![0-9]+]]
 ; CHECK:       test2:
 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne i32 [[A1:%.*]], 0
-; CHECK-NEXT:    br i1 [[CMP1]], label [[BB_JOIN_THREAD:%.*]], label [[TEST2_FALSE:%.*]], !prof [[PROF2:![0-9]+]]
+; CHECK-NEXT:    br i1 [[CMP1]], label [[TMP0:%.*]], label [[TEST2_FALSE:%.*]], !prof [[PROF2:![0-9]+]]
 ; CHECK:       test2_false:
 ; CHECK-NEXT:    call void @foobar()
-; CHECK-NEXT:    br label [[TMP0:%.*]]
+; CHECK-NEXT:    br label [[TMP0]]
 ; CHECK:       bb_join:
 ; CHECK-NEXT:    [[C:%.*]] = phi i1 [ [[CX]], [[ENTRY:%.*]] ]
 ; CHECK-NEXT:    [[COND_FR:%.*]] = freeze i1 [[C]]
-; CHECK-NEXT:    br i1 [[COND_FR]], label [[BB_JOIN_THREAD]], label [[TMP0]], !prof [[PROF3:![0-9]+]]
+; CHECK-NEXT:    br i1 [[COND_FR]], label [[BB_JOIN_THREAD:%.*]], label [[TMP0]], !prof [[PROF3:![0-9]+]]
 ; CHECK:       bb_join.thread:
 ; CHECK-NEXT:    br label [[TMP0]]
 ; CHECK:       0:
-; CHECK-NEXT:    [[TMP1:%.*]] = phi i32 [ 42, [[BB_JOIN_THREAD]] ], [ 7, [[BB_JOIN]] ], [ 7, [[TEST2_FALSE]] ]
+; CHECK-NEXT:    [[TMP1:%.*]] = phi i32 [ 7, [[BB_JOIN]] ], [ 7, [[TEST2_FALSE]] ], [ 42, [[TEST2]] ], [ 42, [[BB_JOIN_THREAD]] ]
 ; CHECK-NEXT:    ret i32 [[TMP1]]
 ;
 entry:
diff --git a/llvm/test/Transforms/SimplifyCFG/pr142242.ll b/llvm/test/Transforms/SimplifyCFG/pr142242.ll
new file mode 100644
index 0000000000000..ec2bcd2c33d6b
--- /dev/null
+++ b/llvm/test/Transforms/SimplifyCFG/pr142242.ll
@@ -0,0 +1,32 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt < %s -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s
+
+define i1 @a_and_b(i1 %a) {
+; CHECK-LABEL: define i1 @a_and_b(
+; CHECK-SAME: i1 [[A:%.*]]) {
+; CHECK-NEXT:  [[START:.*]]:
+; CHECK-NEXT:    br i1 [[A]], label %[[A_IS_TRUE:.*]], label %[[END:.*]]
+; CHECK:       [[A_IS_TRUE]]:
+; CHECK-NEXT:    [[B:%.*]] = call i1 @get_b()
+; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[B]], i1 true, i1 false
+; CHECK-NEXT:    br label %[[END]]
+; CHECK:       [[END]]:
+; CHECK-NEXT:    [[RETVAL:%.*]] = phi i1 [ false, %[[START]] ], [ [[SPEC_SELECT]], %[[A_IS_TRUE]] ]
+; CHECK-NEXT:    ret i1 [[RETVAL]]
+;
+start:
+  br i1 %a, label %a_is_true, label %a_or_b_is_false
+
+a_is_true:
+  %b = call i1 @get_b()
+  br i1 %b, label %end, label %a_or_b_is_false
+
+a_or_b_is_false:
+  br label %end
+
+end:
+  %retval = phi i1 [ true, %a_is_true ], [ false, %a_or_b_is_false ]
+  ret i1 %retval
+}
+
+declare i1 @get_b()

Copy link
Member

@dtcxzyw dtcxzyw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Infinite loop reproducer:

; bin/opt -passes=simplifycfg test.ll -S
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

define void @func_143(i32 %0, ptr %g_329) {
entry:
  switch i32 %0, label %common.ret [
    i32 0, label %for.inc295
    i32 1, label %for.end297
    i32 33, label %for.inc295
  ]

for.inc295:                                       ; preds = %entry, %entry
  br label %for.end297

common.ret:                                       ; preds = %for.end297, %entry
  ret void

for.end297:                                       ; preds = %for.inc295, %entry
  %storemerge739.lcssa761 = phi i64 [ 0, %entry ], [ 1, %for.inc295 ]
  store i8 0, ptr %g_329, align 1
  br label %common.ret
}
opt: /home/dtcxzyw/WorkSpace/Projects/compilers/llvm-project/llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp:249: bool iterativelySimplifyCFG(llvm::Function&, const llvm::TargetTransformInfo&, llvm::DomTreeUpdater*, const llvm::SimplifyCFGOptions&): Assertion `IterCnt++ < 1000 && "Iterative simplification didn't converge!"' failed.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Stack dump:
0.      Program arguments: ./bin/opt -passes=simplifycfg reduced.ll -S
1.      Running pass "function(simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;no-switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-hoist-loads-stores-with-cond-faulting;no-sink-common-insts;speculate-blocks;simplify-cond-branch;no-speculate-unpredictables>)" on module "reduced.ll"
2.      Running pass "simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;no-switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-hoist-loads-stores-with-cond-faulting;no-sink-common-insts;speculate-blocks;simplify-cond-branch;no-speculate-unpredictables>" on function "func_143"
 #0 0x0000728e8f8279f2 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/libLLVMSupport.so.21.0git+0x2279f2)
 #1 0x0000728e8f8248cf llvm::sys::RunSignalHandlers() (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/libLLVMSupport.so.21.0git+0x2248cf)
 #2 0x0000728e8f824a14 SignalHandler(int, siginfo_t*, void*) Signals.cpp:0:0
 #3 0x0000728e8f245330 (/lib/x86_64-linux-gnu/libc.so.6+0x45330)
 #4 0x0000728e8f29eb2c __pthread_kill_implementation ./nptl/pthread_kill.c:44:76
 #5 0x0000728e8f29eb2c __pthread_kill_internal ./nptl/pthread_kill.c:78:10
 #6 0x0000728e8f29eb2c pthread_kill ./nptl/pthread_kill.c:89:10
 #7 0x0000728e8f24527e raise ./signal/../sysdeps/posix/raise.c:27:6
 #8 0x0000728e8f2288ff abort ./stdlib/abort.c:81:7
 #9 0x0000728e8f22881b _nl_load_domain ./intl/loadmsgcat.c:1177:9
#10 0x0000728e8f23b517 (/lib/x86_64-linux-gnu/libc.so.6+0x3b517)
#11 0x0000728e873b78e5 iterativelySimplifyCFG(llvm::Function&, llvm::TargetTransformInfo const&, llvm::DomTreeUpdater*, llvm::SimplifyCFGOptions const&) SimplifyCFGPass.cpp:0:0
#12 0x0000728e873b852c simplifyFunctionCFGImpl(llvm::Function&, llvm::TargetTransformInfo const&, llvm::DominatorTree*, llvm::SimplifyCFGOptions const&) SimplifyCFGPass.cpp:0:0
#13 0x0000728e873b93b5 simplifyFunctionCFG(llvm::Function&, llvm::TargetTransformInfo const&, llvm::DominatorTree*, llvm::SimplifyCFGOptions const&) SimplifyCFGPass.cpp:0:0
#14 0x0000728e873b9510 llvm::SimplifyCFGPass::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/../lib/libLLVMScalarOpts.so.21.0git+0x3b9510)
#15 0x0000728e893ac495 llvm::detail::PassModel<llvm::Function, llvm::SimplifyCFGPass, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/../lib/libPolly.so.21.0git+0x1ac495)
#16 0x0000728e85d27164 llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/../lib/libLLVMCore.so.21.0git+0x327164)
#17 0x0000728e8e2db7c5 llvm::detail::PassModel<llvm::Function, llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function>>, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/../lib/libLLVMX86CodeGen.so.21.0git+0xdb7c5)
#18 0x0000728e85d27680 llvm::ModuleToFunctionPassAdaptor::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/../lib/libLLVMCore.so.21.0git+0x327680)
#19 0x0000728e8e2dc185 llvm::detail::PassModel<llvm::Module, llvm::ModuleToFunctionPassAdaptor, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/../lib/libLLVMX86CodeGen.so.21.0git+0xdc185)
#20 0x0000728e85d28805 llvm::PassManager<llvm::Module, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/../lib/libLLVMCore.so.21.0git+0x328805)
#21 0x0000728e8f9f23d9 llvm::runPassPipeline(llvm::StringRef, llvm::Module&, llvm::TargetMachine*, llvm::TargetLibraryInfoImpl*, llvm::ToolOutputFile*, llvm::ToolOutputFile*, llvm::ToolOutputFile*, llvm::StringRef, llvm::ArrayRef<llvm::PassPlugin>, llvm::ArrayRef<std::function<void (llvm::PassBuilder&)>>, llvm::opt_tool::OutputKind, llvm::opt_tool::VerifierKind, bool, bool, bool, bool, bool, bool, bool) (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/libLLVMOptDriver.so.21.0git+0x2d3d9)
#22 0x0000728e8f9fd416 optMain (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/libLLVMOptDriver.so.21.0git+0x38416)
#23 0x0000728e8f22a1ca __libc_start_call_main ./csu/../sysdeps/nptl/libc_start_call_main.h:74:3
#24 0x0000728e8f22a28b call_init ./csu/../csu/libc-start.c:128:20
#25 0x0000728e8f22a28b __libc_start_main ./csu/../csu/libc-start.c:347:5
#26 0x0000637447eb2095 _start (./bin/opt+0x1095)

Aborted (core dumped)

@dtcxzyw dtcxzyw requested a review from nikic June 3, 2025 12:07
@sharkautarch
Copy link

sharkautarch commented Jun 3, 2025

I did some debugging w/ gdb, & it looks like the infinite loop is happening w/ this pattern of calls within SimplifyCFGOpt::SimplifyOnce:
SimplifyCFGOpt::SimplifyOnce() -- function entry
->
8322 Changed |= ConstantFoldTerminator(BB, /*DeleteDeadConditions=*/true,
------> <ConstantFoldTerminator()+306>: 139 Instruction *T = BB->getTerminator();
------> <ConstantFoldTerminator()>: ret
->
8326 Changed |= EliminateDuplicatePHINodes(BB);
->
8366 Changed |= simplifyBranch(cast<BranchInst>(Terminator), Builder);
------> simplifyUncondBranch()
->
SimplifyCFGOpt::SimplifyOnce() -- function return

Update: ConstantFoldTerminator() seems to return false during this infinite loop, so probably doesn't do anything

@kper
Copy link
Contributor Author

kper commented Jun 4, 2025

Thanks on the info!

At the moment, I think that the issue is in redirectValuesFromPredecessorsToPhi.

# infinite loop
            +--------+
            | entry  |
            +--------+
             / |  \ \
            /  |   \ \
           v   v    \ \
+-------------+      \ \
| for.inc295  |<--+    \ \
+-------------+   |     \ \
                 v      v  v
           +-------------+  \
           | for.end297  |   \
           +-------------+    \
                 |             \
                 v              v
           +-----------------------+
           |      common.ret       |
           +-----------------------+

The goal is that for.inc295 gets merged to for.end297 since it only contains an unconditional jump.
In redirectValuesFromPredecessorsToPhi, we first remove the reference of for.inc295 from the PHI in for.end297.
It skips the check if (isa<PHINode>(OldVal) && cast<PHINode>(OldVal)->getParent() == BB) { and continues in to the else block. The variable BBPreds contains the predecessors of for.inc295 which is entry. However, the common predecessor is also entry. Since both PredBB and CommonPred are entry, it will skip the loop.
Unfortunately, since there is a CommonPred, it will add the old value to the Phi node which is exactly the same thing again. So, the graph did not change at all but simplifyCFG simplification says that something has changed.

@kper kper force-pushed the bugfix/142242-empty-basic branch from 8dff531 to 696d1f7 Compare June 5, 2025 07:28
@github-actions
Copy link

github-actions bot commented Jun 5, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

@kper kper force-pushed the bugfix/142242-empty-basic branch from 696d1f7 to 8074b3d Compare June 5, 2025 08:08
kper added 2 commits June 5, 2025 19:25
If BB and Succ have no phis then then Pred should not be directed to Succ directly.
@kper kper force-pushed the bugfix/142242-empty-basic branch from 8074b3d to ca80824 Compare June 5, 2025 19:25
@kper
Copy link
Contributor Author

kper commented Jun 6, 2025

The goal is that for.inc295 gets merged to for.end297 since it only contains an unconditional jump.

I was not able to get that done. I would have had multiple values from the same bb and I am not sure whether that would be correct. So I just focused on not having the infinity loop.

I've added a check when no values have been redirected then return false. I had to update a few more tests. In some cases, it just reordered the phi values. I hope that's ok.

@sharkautarch
Copy link

The goal is that for.inc295 gets merged to for.end297 since it only contains an unconditional jump.

I was not able to get that done. I would have had multiple values from the same bb and I am not sure whether that would be correct. So I just focused on not having the infinity loop.

I've added a check when no values have been redirected then return false. I had to update a few more tests. In some cases, it just reordered the phi values. I hope that's ok.

In the mentioned infinity loop case, I don’t think the for.inc295 block is mergeable in this case, due to the interaction with the phi node in for.end297
Technically ig the phi node could be removed (which would thereby allow for.inc295 to be merged) by converting the phi node into a select:

define void @func_143(i32 %0, ptr %g_329) {
entry:
  switch i32 %0, label %common.ret [
    i32 0, label %for.end297
    i32 1, label %for.end297
    i32 33, label %for.end297
  ]

common.ret:                                       ; preds = %for.end297, %entry
  ret void

for.end297:                                       ; preds = %entry, %entry, %entry
  %1 = icmp eq i32 %0, 1
  %storemerge739.lcssa761 = select i1 %1, i64 0, i64 1
  store i8 0, ptr %g_329, align 1
  br label %common.ret
}

Not sure if this simplification may already happen with a pass outside simplifycfg (probably not)?
Either way, that’s probably out of scope for this PR?

@kper
Copy link
Contributor Author

kper commented Jun 17, 2025

Technically ig the phi node could be removed (which would thereby allow for.inc295 to be merged) by converting the phi node into a select:

ah ok, nice to know, thanks :)

Not sure if this simplification may already happen with a pass outside simplifycfg (probably not)?
Either way, that’s probably out of scope for this PR?

I think it doesn't. At least when running opt without any passes as argument, it didn't change.
I would prefer to make a separate issue because I am not quite sure how to detect whether I can transform the phi into the select.

EDIT:

I've forgot to run -O3. It seems that the EarlyCSEPass drops the merge and afterwards the SimplifyCFG pass is executed and removes the for.inc295 block.

define void @func_143(i32 %0, ptr writeonly captures(none) %g_329) local_unnamed_addr #0 {
entry:
  switch i32 %0, label %common.ret [
    i32 0, label %for.end297
    i32 1, label %for.end297
    i32 33, label %for.end297
  ]

common.ret:                                       ; preds = %for.end297, %entry
  ret void

for.end297:                                       ; preds = %entry, %entry, %entry
  store i8 0, ptr %g_329, align 1
  br label %common.ret
}

@dtcxzyw
Copy link
Member

dtcxzyw commented Jun 18, 2025

Technically ig the phi node could be removed (which would thereby allow for.inc295 to be merged) by converting the phi node into a select:

ah ok, nice to know, thanks :)

Not sure if this simplification may already happen with a pass outside simplifycfg (probably not)?
Either way, that’s probably out of scope for this PR?

I think it doesn't. At least when running opt without any passes as argument, it didn't change. I would prefer to make a separate issue because I am not quite sure how to detect whether I can transform the phi into the select.

EDIT:

I've forgot to run -O3. It seems that the EarlyCSEPass drops the merge and afterwards the SimplifyCFG pass is executed and removes the for.inc295 block.

define void @func_143(i32 %0, ptr writeonly captures(none) %g_329) local_unnamed_addr #0 {
entry:
  switch i32 %0, label %common.ret [
    i32 0, label %for.end297
    i32 1, label %for.end297
    i32 33, label %for.end297
  ]

common.ret:                                       ; preds = %for.end297, %entry
  ret void

for.end297:                                       ; preds = %entry, %entry, %entry
  store i8 0, ptr %g_329, align 1
  br label %common.ret
}

Not sure if this simplification may already happen with a pass outside simplifycfg (probably not)?
Either way, that’s probably out of scope for this PR?

The reproducer is reduced from the IR just before SimplifyCFGPass. So you cannot rely on other passes to perform the cleanup.

@sharkautarch
Copy link

@kper

I've forgot to run -O3. It seems that the EarlyCSEPass drops the merge and afterwards the SimplifyCFG pass is executed and removes the for.inc295 block.

Lol, I just now realized that %storemerge739.lcssa761 never had any instructions using it to begin with, so the phi & %storemerge739.lcssa761 was always trivial to remove (it probably was used in the original non-reduced form tho…)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Empty basic blocks with unconditional branches aren't eliminated

4 participants