[PATCH] D46426: [SROA] Handle PHI with multiple duplicate predecessors
Bjorn Pettersson via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Wed May 16 13:55:14 PDT 2018
bjope updated this revision to Diff 147173.
bjope added a comment.
Replaced the unordered_map by a DenseMap.
Repository:
rL LLVM
https://reviews.llvm.org/D46426
Files:
lib/Transforms/Scalar/SROA.cpp
test/Transforms/SROA/phi-with-duplicate-pred.ll
Index: test/Transforms/SROA/phi-with-duplicate-pred.ll
===================================================================
--- /dev/null
+++ test/Transforms/SROA/phi-with-duplicate-pred.ll
@@ -0,0 +1,51 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -sroa -S | FileCheck %s
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-n8:16:32:64"
+
+ at a = external global i16, align 1
+
+define void @f2() {
+; CHECK-LABEL: @f2(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br i1 undef, label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
+; CHECK: if.then:
+; CHECK-NEXT: br label [[CLEANUP:%.*]]
+; CHECK: cleanup:
+; CHECK-NEXT: [[G_0_SROA_SPECULATE_LOAD_CLEANUP:%.*]] = load i16, i16* @a, align 1
+; CHECK-NEXT: switch i32 2, label [[CLEANUP7:%.*]] [
+; CHECK-NEXT: i32 0, label [[LBL1:%.*]]
+; CHECK-NEXT: i32 2, label [[LBL1]]
+; CHECK-NEXT: ]
+; CHECK: if.else:
+; CHECK-NEXT: br label [[LBL1]]
+; CHECK: lbl1:
+; CHECK-NEXT: [[G_0_SROA_SPECULATED:%.*]] = phi i16 [ [[G_0_SROA_SPECULATE_LOAD_CLEANUP]], [[CLEANUP]] ], [ [[G_0_SROA_SPECULATE_LOAD_CLEANUP]], [[CLEANUP]] ], [ undef, [[IF_ELSE]] ]
+; CHECK-NEXT: unreachable
+; CHECK: cleanup7:
+; CHECK-NEXT: ret void
+;
+entry:
+ %e = alloca i16, align 1
+ br i1 undef, label %if.then, label %if.else
+
+if.then: ; preds = %entry
+ br label %cleanup
+
+cleanup: ; preds = %if.then
+ switch i32 2, label %cleanup7 [
+ i32 0, label %lbl1
+ i32 2, label %lbl1
+ ]
+
+if.else: ; preds = %entry
+ br label %lbl1
+
+lbl1: ; preds = %if.else, %cleanup, %cleanup
+ %g.0 = phi i16* [ @a, %cleanup ], [ @a, %cleanup ], [ %e, %if.else ]
+ %0 = load i16, i16* %g.0, align 1
+ unreachable
+
+cleanup7: ; preds = %cleanup
+ ret void
+}
+
Index: lib/Transforms/Scalar/SROA.cpp
===================================================================
--- lib/Transforms/Scalar/SROA.cpp
+++ lib/Transforms/Scalar/SROA.cpp
@@ -1261,10 +1261,21 @@
}
// Inject loads into all of the pred blocks.
+ DenseMap<BasicBlock*, Value*> InjectedLoads;
for (unsigned Idx = 0, Num = PN.getNumIncomingValues(); Idx != Num; ++Idx) {
BasicBlock *Pred = PN.getIncomingBlock(Idx);
- TerminatorInst *TI = Pred->getTerminator();
Value *InVal = PN.getIncomingValue(Idx);
+
+ // A PHI node is allowed to have multiple (duplicated) entries for the same
+ // basic block, as long as the value is the same. So if we already injected
+ // a load in the predecessor, then we should reuse the same load for all
+ // duplicated entries.
+ if (Value* V = InjectedLoads.lookup(Pred)) {
+ NewPN->addIncoming(V, Pred);
+ continue;
+ }
+
+ TerminatorInst *TI = Pred->getTerminator();
IRBuilderTy PredBuilder(TI);
LoadInst *Load = PredBuilder.CreateLoad(
@@ -1274,6 +1285,7 @@
if (AATags)
Load->setAAMetadata(AATags);
NewPN->addIncoming(Load, Pred);
+ InjectedLoads[Pred] = Load;
}
LLVM_DEBUG(dbgs() << " speculated to: " << *NewPN << "\n");
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D46426.147173.patch
Type: text/x-patch
Size: 3330 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180516/36f10d7c/attachment.bin>
More information about the llvm-commits
mailing list