Skip to content

Commit 1eb5f61

Browse files
committed
[SROA] Fix GEP(Phi) unfolding when the GEP is inside a spawned task and the Phi is outside of that task.
1 parent a29f696 commit 1eb5f61

2 files changed

Lines changed: 61 additions & 2 deletions

File tree

llvm/lib/Transforms/Scalar/SROA.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4221,9 +4221,11 @@ class AggLoadStoreRewriter : public InstVisitor<AggLoadStoreRewriter, bool> {
42214221

42224222
Type *SourceTy = GEPI.getSourceElementType();
42234223
// We only handle arguments, constants, and static allocas here, so we can
4224-
// insert GEPs at the end of the entry block.
4224+
// insert GEPs at the end of the entry block of the task that contains both
4225+
// the GEP and the Phi. Because the GEP uses the Phi, we use the Phi
4226+
// to determine which task contains both.
42254227
IRB.SetInsertPoint(
4226-
TI->getTaskFor(GEPI.getParent())->getEntry()->getTerminator());
4228+
TI->getTaskFor(Phi->getParent())->getEntry()->getTerminator());
42274229
for (unsigned I = 0, E = Phi->getNumIncomingValues(); I != E; ++I) {
42284230
Value *Op = Phi->getIncomingValue(I);
42294231
BasicBlock *BB = Phi->getIncomingBlock(I);
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
; Check that SROA unfolds gep(phi) appropriately when the gep is inside a task and the phi is outside of the task.
2+
;
3+
; RUN: opt < %s -passes="cgscc(devirt<4>(function<eager-inv;no-rerun>(sroa<modify-cfg>)))" -S | FileCheck %s
4+
5+
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"
6+
target triple = "x86_64-unknown-linux-gnu"
7+
8+
%"class.cv::Mat" = type { i32, i32, i32, i32, ptr, ptr, ptr, ptr, ptr, ptr, %"struct.cv::MatSize", %"struct.cv::MatStep" }
9+
%"struct.cv::MatSize" = type { ptr }
10+
%"struct.cv::MatStep" = type { ptr, [2 x i64] }
11+
12+
define { ptr, i32 } @_ZN2cv5remapERKNS_11_InputArrayERKNS_12_OutputArrayES2_S2_iiRKNS_7Scalar_IdEE() personality ptr null {
13+
entry:
14+
%map1 = alloca %"class.cv::Mat", align 8
15+
%syncreg = call token @llvm.syncregion.start()
16+
call void null(ptr %map1, ptr null)
17+
br label %if.end451
18+
19+
; CHECK: entry:
20+
; CHECK: %[[SROA_GEP:.+]] = getelementptr i8, ptr %map1, i64 16
21+
; CHECK: br label %if.end451
22+
23+
if.end451: ; preds = %entry
24+
%0 = phi ptr [ %map1, %entry ]
25+
br label %pfor.cond
26+
27+
; CHECK: if.end451:
28+
; CHECK: %[[SROA_PHI:.+]] = phi ptr [ %[[SROA_GEP]], %entry ]
29+
; CHECK: br label %pfor.cond
30+
31+
pfor.cond: ; preds = %pfor.cond, %if.end451
32+
detach within %syncreg, label %pfor.body.entry, label %pfor.cond unwind label %lpad889
33+
34+
; CHECK: pfor.cond:
35+
; CHECK-NEXT: detach within %syncreg, label %pfor.body.entry,
36+
37+
pfor.body.entry: ; preds = %pfor.cond
38+
%data.i466 = getelementptr i8, ptr %0, i64 16
39+
br label %for.cond716
40+
41+
; CHECK: pfor.body.entry:
42+
; CHECK-NOT: getelementptr
43+
; CHECK-NEXT: br label %for.cond716
44+
45+
for.cond716: ; preds = %for.cond716, %pfor.body.entry
46+
br label %for.cond716
47+
48+
lpad889: ; preds = %pfor.cond
49+
%1 = landingpad { ptr, i32 }
50+
cleanup
51+
ret { ptr, i32 } %1
52+
}
53+
54+
; Function Attrs: nounwind willreturn memory(argmem: readwrite)
55+
declare token @llvm.syncregion.start() #0
56+
57+
attributes #0 = { nounwind willreturn memory(argmem: readwrite) }

0 commit comments

Comments
 (0)