[flang-commits] [flang] [flang] disable SimplifyPassThroughCondBranch pattern at O0 to preserve line location (PR #227215)

via flang-commits flang-commits at lists.llvm.org
Tue Sep 29 03:32:51 PDT 2026


https://github.com/jeanPerier updated https://github.com/llvm/llvm-project/pull/227215

>From 028881e38f95f807429c7e7eb94aa1d0929de786 Mon Sep 17 00:00:00 2001
From: Jean Perier <jperier at nvidia.com>
Date: Tue, 29 Sep 2026 01:20:55 -0700
Subject: [PATCH 1/2] [flang] disable SimplifyPassThroughCondBranch pattern at
 O0 to preserve line location

---
 flang/lib/Optimizer/Passes/Pipelines.cpp      |  9 ++++-
 .../array-assignment-entry-debug.f90          | 36 +++++++++++++++++++
 2 files changed, 44 insertions(+), 1 deletion(-)
 create mode 100644 flang/test/Integration/array-assignment-entry-debug.f90

diff --git a/flang/lib/Optimizer/Passes/Pipelines.cpp b/flang/lib/Optimizer/Passes/Pipelines.cpp
index ef18ff1cde945..9bff7f936b49d 100644
--- a/flang/lib/Optimizer/Passes/Pipelines.cpp
+++ b/flang/lib/Optimizer/Passes/Pipelines.cpp
@@ -241,7 +241,14 @@ void createDefaultFIRPostCFGOptimizerPassPipeline(
 
   pm.addPass(mlir::createSCFToControlFlowPass());
 
-  pm.addPass(mlir::createCanonicalizerPass(config));
+  // Keep the entry branch of expanded array assignments at O0. Bypassing it
+  // moves the next loop's PHI initializations into the preceding loop header,
+  // losing the statement's breakpoint location outside the loop. Disabling
+  // region simplification alone does not disable this operation pattern.
+  llvm::SmallVector<std::string> disabledPatterns;
+  if (pc.OptLevel == llvm::OptimizationLevel::O0)
+    disabledPatterns.push_back("SimplifyPassThroughCondBranch");
+  pm.addPass(mlir::createCanonicalizerPass(config, disabledPatterns));
   pm.addPass(fir::createSimplifyRegionLite());
   if (!pc.SkipConvertComplexPow)
     pm.addPass(fir::createConvertComplexPow());
diff --git a/flang/test/Integration/array-assignment-entry-debug.f90 b/flang/test/Integration/array-assignment-entry-debug.f90
new file mode 100644
index 0000000000000..a2f0d905a0999
--- /dev/null
+++ b/flang/test/Integration/array-assignment-entry-debug.f90
@@ -0,0 +1,36 @@
+subroutine arrays(a, b, c)
+  integer :: a(4), b(4), c(4)
+  b = 1
+  c = 2
+  a = 11
+  a = b + c
+end subroutine
+
+! Expand the assignments explicitly, without enabling other optimizations.
+! Each following assignment must retain a separate entry branch carrying its
+! source location, outside both the preceding and following loops.
+! RUN: %flang_fc1 -emit-hlfir -mmlir --mlir-print-debuginfo -o - %s | fir-opt --inline-elementals --inline-hlfir-assign --mlir-print-debuginfo -o %t.fir && %flang_fc1 -O0 -debug-info-kind=line-tables-only -emit-llvm %t.fir -o - | FileCheck %s
+
+! CHECK-LABEL: define void @arrays_(
+! CHECK: br label %[[FIRST:[0-9]+]], !dbg ![[LOC1:[0-9]+]]
+! CHECK: [[FIRST]]:
+! CHECK: br i1 {{.*}}, label %{{[0-9]+}}, label %[[ENTRY2:[0-9]+]], !dbg ![[LOC1]]
+! CHECK: [[ENTRY2]]:
+! CHECK-NEXT: br label %[[SECOND:[0-9]+]], !dbg ![[LOC2:[0-9]+]]
+! CHECK: [[SECOND]]:
+! CHECK-NEXT: {{.*}} = phi i64 {{.*}}[ {{[01]}}, %[[ENTRY2]] ]
+! CHECK: br i1 {{.*}}, label %{{[0-9]+}}, label %[[ENTRY3:[0-9]+]], !dbg ![[LOC2]]
+! CHECK: [[ENTRY3]]:
+! CHECK-NEXT: br label %[[THIRD:[0-9]+]], !dbg ![[LOC3:[0-9]+]]
+! CHECK: [[THIRD]]:
+! CHECK-NEXT: {{.*}} = phi i64 {{.*}}[ {{[01]}}, %[[ENTRY3]] ]
+! CHECK: br i1 {{.*}}, label %{{[0-9]+}}, label %[[ENTRY4:[0-9]+]], !dbg ![[LOC3]]
+! CHECK: [[ENTRY4]]:
+! CHECK-NEXT: br label %[[FOURTH:[0-9]+]], !dbg ![[LOC4:[0-9]+]]
+! CHECK: [[FOURTH]]:
+! CHECK-NEXT: {{.*}} = phi i64 {{.*}}[ {{[01]}}, %[[ENTRY4]] ]
+! CHECK: br i1 {{.*}}, !dbg ![[LOC4]]
+! CHECK-DAG: ![[LOC1]] = !DILocation(line: 3, column: 3,
+! CHECK-DAG: ![[LOC2]] = !DILocation(line: 4, column: 3,
+! CHECK-DAG: ![[LOC3]] = !DILocation(line: 5, column: 3,
+! CHECK-DAG: ![[LOC4]] = !DILocation(line: 6, column: 3,

>From 55338475f09a64674300c94681090277354b103d Mon Sep 17 00:00:00 2001
From: Jean Perier <jperier at nvidia.com>
Date: Tue, 29 Sep 2026 02:41:17 -0700
Subject: [PATCH 2/2] update Integration tests that simplified branches

---
 .../parallel-private-reduction-worstcase.f90  | 106 +++++++++---------
 .../test/Integration/cold_array_repacking.f90 |  14 ++-
 2 files changed, 66 insertions(+), 54 deletions(-)

diff --git a/flang/test/Integration/OpenMP/parallel-private-reduction-worstcase.f90 b/flang/test/Integration/OpenMP/parallel-private-reduction-worstcase.f90
index 6d34dc8ec05a7..708a1c56fcbc6 100644
--- a/flang/test/Integration/OpenMP/parallel-private-reduction-worstcase.f90
+++ b/flang/test/Integration/OpenMP/parallel-private-reduction-worstcase.f90
@@ -83,72 +83,72 @@ subroutine worst_case(a, b, c, d)
 ! CHECK:       omp.private.copy12:                               ; preds = %omp.private.copy
 !                [begin firstprivate copy for first var]
 !                [read the length, is it non-zero?]
-! CHECK:         br i1 %{{.*}}, label %omp.private.copy13, label %omp.private.copy22
+! CHECK:         br i1 %{{.*}}, label %omp.private.copy13, label %omp.private.copy23
 
-! CHECK:       omp.private.copy22:                               ; preds = %omp.private.copy21, %omp.private.copy12
+! CHECK:       omp.private.copy23:                               ; preds = %omp.private.copy22, %omp.private.copy12
 ! CHECK-NEXT:    br label %omp.region.cont11
 
-! CHECK:       omp.region.cont11:                                 ; preds = %omp.private.copy22
+! CHECK:       omp.region.cont11:                                 ; preds = %omp.private.copy23
 ! CHECK-NEXT:    %{{.*}} = phi ptr
-! CHECK-NEXT:    br label %omp.private.copy24
+! CHECK-NEXT:    br label %omp.private.copy25
 
-! CHECK:       omp.private.copy24:                               ; preds = %omp.region.cont11
+! CHECK:       omp.private.copy25:                               ; preds = %omp.region.cont11
 !                [begin firstprivate copy for second var]
 !                [read the length, is it non-zero?]
-! CHECK:         br i1 %{{.*}}, label %omp.private.copy25, label %omp.private.copy34
+! CHECK:         br i1 %{{.*}}, label %omp.private.copy26, label %omp.private.copy36
 
-! CHECK:       omp.private.copy34:                               ; preds = %omp.private.copy33, %omp.private.copy24
-! CHECK-NEXT:    br label %omp.region.cont23
+! CHECK:       omp.private.copy36:                               ; preds = %omp.private.copy35, %omp.private.copy25
+! CHECK-NEXT:    br label %omp.region.cont24
 
-! CHECK:       omp.region.cont23:                                ; preds = %omp.private.copy34
+! CHECK:       omp.region.cont24:                                ; preds = %omp.private.copy36
 ! CHECK-NEXT:    %{{.*}} = phi ptr
 ! CHECK-NEXT:    br label %omp.reduction.init
 
-! CHECK:       omp.reduction.init:                               ; preds = %omp.region.cont23
+! CHECK:       omp.reduction.init:                               ; preds = %omp.region.cont24
 !                [deferred stores for results of reduction alloc regions]
 ! CHECK:         br label %[[VAL_96:.*]]
 
 ! CHECK:       omp.reduction.neutral:                            ; preds = %omp.reduction.init
 !                [start of reduction initialization region]
 !                [null check:]
-! CHECK:         br i1 %{{.*}}, label %omp.reduction.neutral36, label %omp.reduction.neutral37
+! CHECK:         br i1 %{{.*}}, label %omp.reduction.neutral38, label %omp.reduction.neutral39
 
-! CHECK:       omp.reduction.neutral37:                          ; preds = %omp.reduction.neutral
+! CHECK:       omp.reduction.neutral39:                          ; preds = %omp.reduction.neutral
 !                [malloc and assign the default value to the reduction variable]
-! CHECK:         br label %omp.reduction.neutral38
+! CHECK:         br label %omp.reduction.neutral40
 
-! CHECK:       omp.reduction.neutral38:                          ; preds = %omp.reduction.neutral36, %omp.reduction.neutral37
-! CHECK-NEXT:    br label %omp.region.cont35
+! CHECK:       omp.reduction.neutral40:                          ; preds = %omp.reduction.neutral38, %omp.reduction.neutral39
+! CHECK-NEXT:    br label %omp.region.cont37
 
-! CHECK:       omp.region.cont35:                                ; preds = %omp.reduction.neutral38
+! CHECK:       omp.region.cont37:                                ; preds = %omp.reduction.neutral40
 ! CHECK-NEXT:    %{{.*}} = phi ptr
-! CHECK-NEXT:    br label %omp.reduction.neutral40
+! CHECK-NEXT:    br label %omp.reduction.neutral42
 
-! CHECK:       omp.reduction.neutral40:                          ; preds = %omp.region.cont35
+! CHECK:       omp.reduction.neutral42:                          ; preds = %omp.region.cont37
 !                [start of reduction initialization region]
 !                [null check:]
-! CHECK:         br i1 %{{.*}}, label %omp.reduction.neutral41, label %omp.reduction.neutral42
+! CHECK:         br i1 %{{.*}}, label %omp.reduction.neutral43, label %omp.reduction.neutral44
 
-! CHECK:       omp.reduction.neutral42:                          ; preds = %omp.reduction.neutral40
+! CHECK:       omp.reduction.neutral44:                          ; preds = %omp.reduction.neutral42
 !                [malloc and assign the default value to the reduction variable]
-! CHECK:         br label %omp.reduction.neutral43
+! CHECK:         br label %omp.reduction.neutral45
 
-! CHECK:       omp.reduction.neutral43:                          ; preds = %omp.reduction.neutral41, %omp.reduction.neutral42
-! CHECK-NEXT:    br label %omp.region.cont39
+! CHECK:       omp.reduction.neutral45:                          ; preds = %omp.reduction.neutral43, %omp.reduction.neutral44
+! CHECK-NEXT:    br label %omp.region.cont41
 
-! CHECK:       omp.region.cont39:                                ; preds = %omp.reduction.neutral43
+! CHECK:       omp.region.cont41:                                ; preds = %omp.reduction.neutral45
 ! CHECK-NEXT:    %{{.*}} = phi ptr
-! CHECK-NEXT:    br label %omp.par.region45
+! CHECK-NEXT:    br label %omp.par.region47
 
-! CHECK:       omp.par.region45:                                 ; preds = %omp.region.cont39
+! CHECK:       omp.par.region47:                                 ; preds = %omp.region.cont41
 !                [call SUM runtime function]
 !                [if (sum(a) == 1)]
-! CHECK:         br i1 %{{.*}}, label %omp.par.region46, label %omp.par.region47
+! CHECK:         br i1 %{{.*}}, label %omp.par.region48, label %omp.par.region49
 
-! CHECK:       omp.par.region47:                                 ; preds = %omp.par.region45
-! CHECK-NEXT:    br label %omp.region.cont44
+! CHECK:       omp.par.region49:                                 ; preds = %omp.par.region47
+! CHECK-NEXT:    br label %omp.region.cont46
 
-! CHECK:       omp.region.cont44:                                ; preds = %omp.par.region47
+! CHECK:       omp.region.cont46:                                ; preds = %omp.par.region49
 !                [omp parallel region done, call into the runtime to complete reduction]
 ! CHECK:         %[[VAL_233:.*]] = call i32 @__kmpc_reduce(
 ! CHECK:         switch i32 %[[VAL_233]], label %reduce.finalize [
@@ -156,16 +156,16 @@ subroutine worst_case(a, b, c, d)
 ! CHECK-NEXT:      i32 2, label %reduce.switch.atomic
 ! CHECK-NEXT:    ]
 
-! CHECK:       reduce.switch.atomic:                             ; preds = %omp.region.cont44
+! CHECK:       reduce.switch.atomic:                             ; preds = %omp.region.cont46
 ! CHECK-NEXT:    unreachable
 
-! CHECK:       reduce.switch.nonatomic:                          ; preds = %omp.region.cont44
+! CHECK:       reduce.switch.nonatomic:                          ; preds = %omp.region.cont46
 ! CHECK-NEXT:    %[[red_private_value_0:.*]] = load ptr, ptr %{{.*}}, align 8
 ! CHECK-NEXT:    br label %omp.reduction.nonatomic.body
 
 !              [various blocks implementing the reduction]
 
-! CHECK:       omp.region.cont52:                                ; preds =
+! CHECK:       omp.region.cont54:                                ; preds =
 ! CHECK-NEXT:    %{{.*}} = phi ptr
 ! CHECK-NEXT:    call void @__kmpc_end_reduce(
 ! CHECK-NEXT:    br label %reduce.finalize
@@ -182,38 +182,44 @@ subroutine worst_case(a, b, c, d)
 
 ! CHECK:       omp.reduction.cleanup:                            ; preds = %.fini
 !                [null check]
-! CHECK:         br i1 %{{.*}}, label %omp.reduction.cleanup58, label %omp.reduction.cleanup59
+! CHECK:         br i1 %{{.*}}, label %omp.reduction.cleanup60, label %omp.reduction.cleanup61
 
-! CHECK:       omp.reduction.cleanup59:                          ; preds = %omp.reduction.cleanup58, %omp.reduction.cleanup
-! CHECK-NEXT:    br label %omp.region.cont57
+! CHECK:       omp.reduction.cleanup61:                          ; preds = %omp.reduction.cleanup60, %omp.reduction.cleanup
+! CHECK-NEXT:    br label %omp.region.cont59
 
-! CHECK:       omp.region.cont57:                                ; preds = %omp.reduction.cleanup59
+! CHECK:       omp.region.cont59:                                ; preds = %omp.reduction.cleanup61
 ! CHECK-NEXT:    %{{.*}} = load ptr, ptr
-! CHECK-NEXT:    br label %omp.reduction.cleanup61
+! CHECK-NEXT:    br label %omp.reduction.cleanup63
 
-! CHECK:       omp.reduction.cleanup61:                          ; preds = %omp.region.cont57
+! CHECK:       omp.reduction.cleanup63:                          ; preds = %omp.region.cont59
 !                [null check]
-! CHECK:         br i1 %{{.*}}, label %omp.reduction.cleanup62, label %omp.reduction.cleanup63
+! CHECK:         br i1 %{{.*}}, label %omp.reduction.cleanup64, label %omp.reduction.cleanup65
 
-! CHECK:       omp.par.region46:                                 ; preds = %omp.par.region45
+! CHECK:       omp.par.region48:                                 ; preds = %omp.par.region47
 ! CHECK-NEXT:    call void @_FortranAStopStatement
 ! CHECK-NEXT:    unreachable
 
-! CHECK:       omp.reduction.neutral41:                          ; preds = %omp.reduction.neutral40
+! CHECK:       omp.reduction.neutral43:                          ; preds = %omp.reduction.neutral42
 !                [source length was zero: finish initializing array]
-! CHECK:         br label %omp.reduction.neutral43
+! CHECK:         br label %omp.reduction.neutral45
 
-! CHECK:       omp.reduction.neutral36:                          ; preds = %omp.reduction.neutral
+! CHECK:       omp.reduction.neutral38:                          ; preds = %omp.reduction.neutral
 !                [source length was zero: finish initializing array]
-! CHECK:         br label %omp.reduction.neutral38
+! CHECK:         br label %omp.reduction.neutral40
 
-! CHECK:       omp.private.copy33:                               ; preds = %omp.private.copy32, %omp.private.copy29
+! CHECK:       omp.private.copy35:                               ; preds = %omp.private.copy34, %omp.private.copy31
 !                [source length was non-zero: call assign runtime]
-! CHECK:         br label %omp.private.copy34
+! CHECK:         br label %omp.private.copy36
 
-! CHECK:       omp.private.copy21:                               ; preds = %omp.private.copy20, %omp.private.copy17
+! CHECK:       omp.private.copy29:                               ; preds = %omp.private.copy27
+! CHECK-NEXT:    br label %omp.private.copy31
+
+! CHECK:       omp.private.copy22:                               ; preds = %omp.private.copy21, %omp.private.copy18
 !                [source length was non-zero: call assign runtime]
-! CHECK:         br label %omp.private.copy22
+! CHECK:         br label %omp.private.copy23
+
+! CHECK:       omp.private.copy16:                               ; preds = %omp.private.copy14
+! CHECK-NEXT:    br label %omp.private.copy18
 
 ! CHECK:       omp.private.init8:                               ; preds = %omp.private.init7
 !                [var extent was non-zero: malloc a private array]
@@ -223,5 +229,5 @@ subroutine worst_case(a, b, c, d)
 !                [var extent was non-zero: malloc a private array]
 ! CHECK:         br label %omp.private.init5
 
-! CHECK:       omp.par.exit.exitStub:                           ; preds = %omp.region.cont67
+! CHECK:       omp.par.exit.exitStub:                           ; preds = %omp.region.cont69
 ! CHECK-NEXT:    ret void
diff --git a/flang/test/Integration/cold_array_repacking.f90 b/flang/test/Integration/cold_array_repacking.f90
index 2a3769e381784..1151137cf65ba 100644
--- a/flang/test/Integration/cold_array_repacking.f90
+++ b/flang/test/Integration/cold_array_repacking.f90
@@ -6,22 +6,28 @@
 ! CHECK-SAME:      ptr noalias [[TMP0:%.*]])
 ! CHECK:    [[TMP4:%.*]] = ptrtoint ptr [[TMP0]] to i64
 ! CHECK:    [[TMP5:%.*]] = icmp ne i64 [[TMP4]], 0
-! CHECK:    br i1 [[TMP5]], label %[[BB6:.*]], label %[[BB46:.*]]
+! CHECK:    br i1 [[TMP5]], label %[[BB6:.*]], label %[[ABSENT:.*]]
 ! CHECK:  [[BB6]]:
 ! CHECK:    [[TMP7:%.*]] = call i1 @_FortranAIsContiguous(ptr [[TMP0]])
 ! CHECK:    [[TMP8:%.*]] = icmp eq i1 [[TMP7]], false
 ! CHECK:    [[TMP13:%.*]] = and i1 [[TMP8]], [[TMP12:.*]]
-! CHECK:    br i1 [[TMP13]], label %[[BB14:.*]], label %[[BB46]], !prof [[PROF2:![0-9]+]]
+! CHECK:    br i1 [[TMP13]], label %[[BB14:.*]], label %[[NO_REPACK:.*]], !prof [[PROF2:![0-9]+]]
 ! CHECK:  [[BB14]]:
 ! CHECK:    call void @_FortranAShallowCopyDirect
-! CHECK:    br label %[[BB46]]
+! CHECK:    br label %[[BB46:.*]]
+! CHECK:  [[NO_REPACK]]:
+! CHECK-NEXT: br label %[[BB46]]
+! CHECK:  [[ABSENT]]:
+! CHECK-NEXT: br label %[[BB46]]
 ! CHECK:  [[BB46]]:
 ! CHECK:    br i1 [[TMP5]], label %[[BB48:.*]], label %[[BB57:.*]]
 ! CHECK:  [[BB48]]:
-! CHECK:    br i1 [[TMP55:.*]], label %[[BB56:.*]], label %[[BB57]], !prof [[PROF2]]
+! CHECK:    br i1 [[TMP55:.*]], label %[[BB56:.*]], label %[[NO_COPY_BACK:.*]], !prof [[PROF2]]
 ! CHECK:  [[BB56]]:
 ! CHECK:    call void @_FortranAShallowCopyDirect
 ! CHECK:    br label %[[BB57]]
+! CHECK:  [[NO_COPY_BACK]]:
+! CHECK-NEXT: br label %[[BB57]]
 ! CHECK:  [[BB57]]:
 ! CHECK:    ret void
 ! CHECK: [[PROF2]] = !{!"branch_weights", i32 0, i32 1}



More information about the flang-commits mailing list