Skip to content

Commit 3055b89

Browse files
committed
[mlir][OpenMP] fix crash outlining infinite loop
Previously an extra block was created by splitting the previous exit block. This produced incorrect results when the outlined region statically never terminated because then there wouldn't be a valid exit block for the outlined region, this caused this newly added block to have an incoming edge from outside of the outlining region, which caused outlining to fail. So far as I can tell this extra block no longer serves any purpose. The comment says it is supposed to collate multiple control flow edges into one place, but the code as it is now does not achieve this. In fact, as can be seen from the changes to lit tests, this block was not actually outlined in the end. This is because there are actually two code extractors: one in the callback for creating a parallel op which is used to find what the input/output variables are (which does have this block added to it), and another one which actually does the outlining (which this block was not added to). Tested with the gfortran and fujitsu test suites.
1 parent 4396237 commit 3055b89

File tree

8 files changed

+52
-22
lines changed

8 files changed

+52
-22
lines changed

flang/test/Integration/OpenMP/parallel-private-reduction-worstcase.f90

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,5 +219,5 @@ subroutine worst_case(a, b, c, d)
219219
! [var extent was non-zero: malloc a private array]
220220
! CHECK: br label %omp.private.init5
221221

222-
! CHECK: omp.par.outlined.exit.exitStub: ; preds = %omp.region.cont52
222+
! CHECK: omp.par.exit.exitStub: ; preds = %omp.region.cont52
223223
! CHECK-NEXT: ret void

llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1602,14 +1602,6 @@ OpenMPIRBuilder::InsertPointOrErrorTy OpenMPIRBuilder::createParallel(
16021602
SmallVector<BasicBlock *, 32> Blocks;
16031603
OI.collectBlocks(ParallelRegionBlockSet, Blocks);
16041604

1605-
// Ensure a single exit node for the outlined region by creating one.
1606-
// We might have multiple incoming edges to the exit now due to finalizations,
1607-
// e.g., cancel calls that cause the control flow to leave the region.
1608-
BasicBlock *PRegOutlinedExitBB = PRegExitBB;
1609-
PRegExitBB = SplitBlock(PRegExitBB, &*PRegExitBB->getFirstInsertionPt());
1610-
PRegOutlinedExitBB->setName("omp.par.outlined.exit");
1611-
Blocks.push_back(PRegOutlinedExitBB);
1612-
16131605
CodeExtractorAnalysisCache CEAC(*OuterFn);
16141606
CodeExtractor Extractor(Blocks, /* DominatorTree */ nullptr,
16151607
/* AggregateArgs */ false,

mlir/test/Target/LLVMIR/openmp-llvm.mlir

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -162,14 +162,12 @@ llvm.func @test_omp_parallel_if_1(%arg0: i32) -> () {
162162
// CHECK: %[[I32_IF_COND_VAR_1:.*]] = sext i1 %[[IF_COND_VAR_1]] to i32
163163
// CHECK: call void @__kmpc_fork_call_if(ptr @[[SI_VAR_IF_1]], i32 0, ptr @[[OMP_OUTLINED_FN_IF_1:.*]], i32 %[[I32_IF_COND_VAR_1]], ptr null)
164164
// CHECK: br label %[[OUTLINED_EXIT_IF_1:.*]]
165-
// CHECK: [[OUTLINED_EXIT_IF_1]]:
166-
// CHECK: br label %[[RETURN_BLOCK_IF_1:.*]]
167165
omp.parallel if(%1) {
168166
omp.barrier
169167
omp.terminator
170168
}
171169

172-
// CHECK: [[RETURN_BLOCK_IF_1]]:
170+
// CHECK: [[OUTLINED_EXIT_IF_1]]:
173171
// CHECK: ret void
174172
llvm.return
175173
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// RUN: mlir-translate -mlir-to-llvmir %s | FileCheck %s
2+
3+
// Test that trying to outline an infinite loop doesn't lead to an assertion
4+
// failure.
5+
6+
llvm.func @parallel_infinite_loop() -> () {
7+
omp.parallel {
8+
llvm.br ^bb1
9+
^bb1:
10+
llvm.br ^bb1
11+
}
12+
llvm.return
13+
}
14+
15+
// CHECK-LABEL: define void @parallel_infinite_loop() {
16+
// CHECK: %[[VAL_2:.*]] = call i32 @__kmpc_global_thread_num(ptr @1)
17+
// CHECK: br label %[[VAL_3:.*]]
18+
// CHECK: omp_parallel:
19+
// CHECK: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @1, i32 0, ptr @parallel_infinite_loop..omp_par)
20+
// CHECK: unreachable
21+
// CHECK: omp.region.cont: ; No predecessors!
22+
// CHECK: br label %[[VAL_4:.*]]
23+
// CHECK: omp.par.pre_finalize: ; preds = %[[VAL_5:.*]]
24+
// CHECK: br label %[[VAL_6:.*]]
25+
// CHECK: omp.par.exit: ; preds = %[[VAL_4]]
26+
// CHECK: ret void
27+
// CHECK: }
28+
29+
// CHECK-LABEL: define internal void @parallel_infinite_loop..omp_par(
30+
// CHECK-SAME: ptr noalias %[[TID_ADDR:.*]], ptr noalias %[[ZERO_ADDR:.*]])
31+
// CHECK: omp.par.entry:
32+
// CHECK: %[[VAL_7:.*]] = alloca i32, align 4
33+
// CHECK: %[[VAL_8:.*]] = load i32, ptr %[[VAL_9:.*]], align 4
34+
// CHECK: store i32 %[[VAL_8]], ptr %[[VAL_7]], align 4
35+
// CHECK: %[[VAL_10:.*]] = load i32, ptr %[[VAL_7]], align 4
36+
// CHECK: br label %[[VAL_11:.*]]
37+
// CHECK: omp.region.after_alloca: ; preds = %[[VAL_12:.*]]
38+
// CHECK: br label %[[VAL_13:.*]]
39+
// CHECK: omp.par.region: ; preds = %[[VAL_11]]
40+
// CHECK: br label %[[VAL_14:.*]]
41+
// CHECK: omp.par.region1: ; preds = %[[VAL_13]]
42+
// CHECK: br label %[[VAL_15:.*]]
43+
// CHECK: omp.par.region2: ; preds = %[[VAL_15]], %[[VAL_14]]
44+
// CHECK: br label %[[VAL_15]]

mlir/test/Target/LLVMIR/openmp-parallel-reduction-multiblock.mlir

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,7 @@ llvm.func @missordered_blocks_(%arg0: !llvm.ptr {fir.bindc_name = "x"}, %arg1: !
4040
// CHECK: store ptr %[[VAL_8:.*]], ptr %[[VAL_7]], align 8
4141
// CHECK: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @1, i32 1, ptr @missordered_blocks_..omp_par, ptr %[[VAL_0]])
4242
// CHECK: br label %[[VAL_9:.*]]
43-
// CHECK: omp.par.outlined.exit: ; preds = %[[VAL_4]]
44-
// CHECK: br label %[[VAL_10:.*]]
45-
// CHECK: omp.par.exit.split: ; preds = %[[VAL_9]]
43+
// CHECK: omp.par.exit: ; preds = %[[VAL_4]]
4644
// CHECK: ret void
4745
// CHECK: [[PAR_ENTRY:omp.par.entry]]:
4846
// CHECK: %[[VAL_11:.*]] = getelementptr { ptr, ptr }, ptr %[[VAL_12:.*]], i32 0, i32 0
@@ -117,5 +115,5 @@ llvm.func @missordered_blocks_(%arg0: !llvm.ptr {fir.bindc_name = "x"}, %arg1: !
117115
// CHECK: br label %[[VAL_38]]
118116
// CHECK: omp.reduction.neutral1: ; preds = %[[VAL_25]]
119117
// CHECK: br label %[[VAL_30]]
120-
// CHECK: omp.par.outlined.exit.exitStub: ; preds = %[[VAL_53]]
118+
// CHECK: omp.par.exit.exitStub: ; preds = %[[VAL_53]]
121119
// CHECK: ret void

mlir/test/Target/LLVMIR/openmp-reduction-array-sections.mlir

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,5 +219,5 @@ llvm.func @sectionsreduction_(%arg0: !llvm.ptr {fir.bindc_name = "x"}) attribute
219219
// CHECK: omp_section_loop.inc: ; preds = %[[VAL_69]]
220220
// CHECK: %[[VAL_31]] = add nuw i32 %[[VAL_30]], 1
221221
// CHECK: br label %[[VAL_28]]
222-
// CHECK: omp.par.outlined.exit.exitStub: ; preds = %[[VAL_64]]
222+
// CHECK: omp.par.exit.exitStub: ; preds = %[[VAL_64]]
223223
// CHECK: ret void

mlir/test/Target/LLVMIR/openmp-reduction-init-arg.mlir

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,7 @@ module {
4646
// CHECK: store ptr %[[VAL_2]], ptr %[[VAL_8]], align 8
4747
// CHECK: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @1, i32 1, ptr @_QFPreduce..omp_par, ptr %[[VAL_0]])
4848
// CHECK: br label %[[VAL_9:.*]]
49-
// CHECK: omp.par.outlined.exit: ; preds = %[[VAL_6]]
50-
// CHECK: br label %[[VAL_10:.*]]
51-
// CHECK: omp.par.exit.split: ; preds = %[[VAL_9]]
49+
// CHECK: omp.par.exit: ; preds = %[[VAL_6]]
5250
// CHECK: ret void
5351
// CHECK: [[PAR_ENTRY:omp.par.entry]]:
5452
// CHECK: %[[VAL_11:.*]] = getelementptr { ptr, ptr }, ptr %[[VAL_12:.*]], i32 0, i32 0
@@ -99,7 +97,7 @@ module {
9997
// CHECK: br label %[[VAL_38:.*]]
10098
// CHECK: omp.par.pre_finalize: ; preds = %[[VAL_33]]
10199
// CHECK: br label %[[VAL_39:.*]]
102-
// CHECK: omp.par.outlined.exit.exitStub: ; preds = %[[VAL_38]]
100+
// CHECK: omp.par.exit.exitStub: ; preds = %[[VAL_38]]
103101
// CHECK: ret void
104102
// CHECK: %[[VAL_40:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_41:.*]], i64 0, i64 0
105103
// CHECK: %[[VAL_42:.*]] = load ptr, ptr %[[VAL_40]], align 8

mlir/test/Target/LLVMIR/openmp-reduction-sections.mlir

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ llvm.func @sections_(%arg0: !llvm.ptr {fir.bindc_name = "x"}) attributes {fir.in
144144
// CHECK: omp_section_loop.inc: ; preds = %[[VAL_59]]
145145
// CHECK: %[[VAL_35]] = add nuw i32 %[[VAL_34]], 1
146146
// CHECK: br label %[[VAL_32]]
147-
// CHECK: omp.par.outlined.exit.exitStub: ; preds = %[[VAL_54]]
147+
// CHECK: omp.par.exit.exitStub: ; preds = %[[VAL_54]]
148148
// CHECK: ret void
149149
// CHECK: %[[VAL_70:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_71:.*]], i64 0, i64 0
150150
// CHECK: %[[VAL_72:.*]] = load ptr, ptr %[[VAL_70]], align 8

0 commit comments

Comments
 (0)