https://github.com/firmiana402 updated https://github.com/llvm/llvm-project/pull/207129
>From ba7fc7db1b7986fa976e738ffb6801e0aae143ee Mon Sep 17 00:00:00 2001 From: firmiana402 <[email protected]> Date: Thu, 2 Jul 2026 14:09:03 +0800 Subject: [PATCH 1/3] [Clang][CodeGen] Fold forwarding blocks after nested else control flow --- clang/lib/CodeGen/CGStmt.cpp | 6 ++ .../else-nested-control-flow-forwarding.c | 56 +++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 clang/test/DebugInfo/Generic/else-nested-control-flow-forwarding.c diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp index 232094777f233..1e79138ed8f82 100644 --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -987,9 +987,15 @@ void CodeGenFunction::EmitIfStmt(const IfStmt &S) { EmitStmt(Else); } { + llvm::BasicBlock *ElseExitBlock = Builder.GetInsertBlock(); // There is no need to emit line number for an unconditional branch. auto NL = ApplyDebugLocation::CreateEmpty(*this); EmitBranch(ContBlock); + + // If nested control flow in the else body left behind a synthetic + // continuation, fold it into this if's continuation when possible. + if (ElseExitBlock && ElseExitBlock != ElseBlock) + SimplifyForwardingBlocks(ElseExitBlock); } } else if (HasSkip) { EmitBlock(ElseBlock); diff --git a/clang/test/DebugInfo/Generic/else-nested-control-flow-forwarding.c b/clang/test/DebugInfo/Generic/else-nested-control-flow-forwarding.c new file mode 100644 index 0000000000000..39d19233763fc --- /dev/null +++ b/clang/test/DebugInfo/Generic/else-nested-control-flow-forwarding.c @@ -0,0 +1,56 @@ +// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -triple x86_64-unknown-linux-gnu %s -o - | FileCheck %s + +// Nested control flow at the end of an else body can leave behind an empty +// continuation block that only forwards to the outer if continuation. Avoid +// emitting that extra block. + +// CHECK-LABEL: define {{.*}} @else_if_chain( +// CHECK: if.end: +// CHECK-NOT: if.end{{[0-9]+}}: +// CHECK: ret + +int else_if_chain(int i, int *arr) { + int x = 0; + if (i == 1) { + x = i + 1; + } else if (i == 2) { + arr[i] = 42; + } + return x; +} + +// CHECK-LABEL: define {{.*}} @nested_if_in_else( +// CHECK: if.end: +// CHECK-NOT: if.end{{[0-9]+}}: +// CHECK: ret + +int nested_if_in_else(int i, int *arr) { + int x = 0; + if (i == 1) { + x = i + 1; + } else { + if (i == 2) { + arr[i] = 42; + } + } + return x; +} + +// CHECK-LABEL: define {{.*}} @else_if_chain_with_final_else( +// CHECK: if.end: +// CHECK-NOT: if.end{{[0-9]+}}: +// CHECK: ret + +int else_if_chain_with_final_else(int i) { + int x = 0; + if (i == 1) { + x = 1; + } else if (i == 2) { + x = 2; + } else if (i == 3) { + x = 3; + } else { + x = 4; + } + return x; +} >From 6e6673f9b8db8928089a88ee45453236ed8cbb61 Mon Sep 17 00:00:00 2001 From: firmiana402 <[email protected]> Date: Thu, 2 Jul 2026 14:23:37 +0800 Subject: [PATCH 2/3] [Clang][test] Update CPU supports CFG checks --- clang/test/CodeGen/builtin-cpu-supports.c | 32 ++--------------------- 1 file changed, 2 insertions(+), 30 deletions(-) diff --git a/clang/test/CodeGen/builtin-cpu-supports.c b/clang/test/CodeGen/builtin-cpu-supports.c index 1ace52b7de8f1..6e56b72c99dc6 100644 --- a/clang/test/CodeGen/builtin-cpu-supports.c +++ b/clang/test/CodeGen/builtin-cpu-supports.c @@ -196,25 +196,9 @@ int v4() { return __builtin_cpu_supports("x86-64-v4"); } // CHECK-PPC-NEXT: store i32 [[SUB27]], ptr [[RETVAL]], align 4 // CHECK-PPC-NEXT: br label [[RETURN]] // CHECK-PPC: if.end: -// CHECK-PPC-NEXT: br label [[IF_END28:%.*]] -// CHECK-PPC: if.end28: -// CHECK-PPC-NEXT: br label [[IF_END29:%.*]] -// CHECK-PPC: if.end29: -// CHECK-PPC-NEXT: br label [[IF_END30:%.*]] -// CHECK-PPC: if.end30: -// CHECK-PPC-NEXT: br label [[IF_END31:%.*]] -// CHECK-PPC: if.end31: -// CHECK-PPC-NEXT: br label [[IF_END32:%.*]] -// CHECK-PPC: if.end32: -// CHECK-PPC-NEXT: br label [[IF_END33:%.*]] -// CHECK-PPC: if.end33: -// CHECK-PPC-NEXT: br label [[IF_END34:%.*]] -// CHECK-PPC: if.end34: -// CHECK-PPC-NEXT: br label [[IF_END35:%.*]] -// CHECK-PPC: if.end35: // CHECK-PPC-NEXT: [[TMP21:%.*]] = load i32, ptr [[A_ADDR]], align 4 -// CHECK-PPC-NEXT: [[ADD36:%.*]] = add nsw i32 [[TMP21]], 5 -// CHECK-PPC-NEXT: store i32 [[ADD36]], ptr [[RETVAL]], align 4 +// CHECK-PPC-NEXT: [[ADD28:%.*]] = add nsw i32 [[TMP21]], 5 +// CHECK-PPC-NEXT: store i32 [[ADD28]], ptr [[RETVAL]], align 4 // CHECK-PPC-NEXT: br label [[RETURN]] // CHECK-PPC: return: // CHECK-PPC-NEXT: [[TMP22:%.*]] = load i32, ptr [[RETVAL]], align 4 @@ -283,12 +267,6 @@ int test_ppc(int a) { // CHECK-RV32-NEXT: store i32 13, ptr [[RETVAL]], align 4 // CHECK-RV32-NEXT: br label [[RETURN]] // CHECK-RV32: if.end: -// CHECK-RV32-NEXT: br label [[IF_END6:%.*]] -// CHECK-RV32: if.end6: -// CHECK-RV32-NEXT: br label [[IF_END7:%.*]] -// CHECK-RV32: if.end7: -// CHECK-RV32-NEXT: br label [[IF_END8:%.*]] -// CHECK-RV32: if.end8: // CHECK-RV32-NEXT: store i32 0, ptr [[RETVAL]], align 4 // CHECK-RV32-NEXT: br label [[RETURN]] // CHECK-RV32: return: @@ -334,12 +312,6 @@ int test_ppc(int a) { // CHECK-RV64-NEXT: store i32 13, ptr [[RETVAL]], align 4 // CHECK-RV64-NEXT: br label [[RETURN]] // CHECK-RV64: if.end: -// CHECK-RV64-NEXT: br label [[IF_END6:%.*]] -// CHECK-RV64: if.end6: -// CHECK-RV64-NEXT: br label [[IF_END7:%.*]] -// CHECK-RV64: if.end7: -// CHECK-RV64-NEXT: br label [[IF_END8:%.*]] -// CHECK-RV64: if.end8: // CHECK-RV64-NEXT: store i32 0, ptr [[RETVAL]], align 4 // CHECK-RV64-NEXT: br label [[RETURN]] // CHECK-RV64: return: >From 82e63b482ad96893aaf566680979e224920e7234 Mon Sep 17 00:00:00 2001 From: firmiana402 <[email protected]> Date: Thu, 2 Jul 2026 20:13:40 +0800 Subject: [PATCH 3/3] [Clang][CodeGen] Avoid folding else label targets Do not simplify an else-body forwarding block when the block is the destination of a source label. Such blocks may still be referenced by later gotos or address-of-label expressions, so they do not satisfy SimplifyForwardingBlocks' safety precondition. --- clang/lib/CodeGen/CGStmt.cpp | 6 ++++-- clang/lib/CodeGen/CodeGenFunction.h | 10 ++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp index 1e79138ed8f82..dce37c37a9b51 100644 --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -993,8 +993,10 @@ void CodeGenFunction::EmitIfStmt(const IfStmt &S) { EmitBranch(ContBlock); // If nested control flow in the else body left behind a synthetic - // continuation, fold it into this if's continuation when possible. - if (ElseExitBlock && ElseExitBlock != ElseBlock) + // continuation, fold it into this if's continuation when possible. Do not + // fold source-label targets, as they may still be referenced. + if (ElseExitBlock && ElseExitBlock != ElseBlock && + !isLabelTarget(ElseExitBlock)) SimplifyForwardingBlocks(ElseExitBlock); } } else if (HasSkip) { diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 6d0718c243812..337331269e5e6 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -427,6 +427,16 @@ class CodeGenFunction : public CodeGenTypeCache { return !LabelMap.empty(); } + /// Return true if this basic block is the destination for a source label. + bool isLabelTarget(const llvm::BasicBlock *BB) const { + if (!BB) + return false; + for (const auto &LabelAndDest : LabelMap) + if (LabelAndDest.second.getBlock() == BB) + return true; + return false; + } + /// AllocaInsertPoint - This is an instruction in the entry block before which /// we prefer to insert allocas. llvm::AssertingVH<llvm::Instruction> AllocaInsertPt; _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
