// Okay, apparently we need to look at predecessors.
- BasicBlock *UseBB = OrigIVI.getParent();
+ // We should be smart about picking the "use" basic block, which will be the
+ // merge point for aggregate, where we'll insert the final PHI that will be
+ // used instead of OrigIVI. Basic block of OrigIVI is *not* the right choice.
+ // We should look in which blocks each of the AggElts is being defined,
+ // they all should be defined in the same basic block.
+ BasicBlock *UseBB = nullptr;
+
+ for (const Optional<Value *> &Elt : AggElts) {
+ // If this element's value was not defined by an instruction, ignore it.
+ auto *I = dyn_cast<Instruction>(*Elt);
+ if (!I)
+ continue;
+ // Otherwise, in which basic block is this instruction located?
+ BasicBlock *BB = I->getParent();
+ // If it's the first instruction we've encountered, record the basic block.
+ if (!UseBB) {
+ UseBB = BB;
+ continue;
+ }
+ // Otherwise, this must be the same basic block we've seen previously.
+ if (UseBB != BB)
+ return nullptr;
+ }
// If *all* of the elements are basic-block-independent, meaning they are
// either function arguments, or constant expressions, then if we didn't
- // handle them without predecessor-aware folding, we won't handle them now.
+ // handle them without predecessor-aware handling, we won't handle them now.
if (!UseBB)
return nullptr;
; CHECK-NEXT: entry:
; CHECK-NEXT: br i1 [[C0:%.*]], label [[LEFT:%.*]], label [[RIGHT:%.*]]
; CHECK: left:
-; CHECK-NEXT: [[I0:%.*]] = extractvalue { i32, i32 } [[AGG_LEFT:%.*]], 0
-; CHECK-NEXT: [[I2:%.*]] = extractvalue { i32, i32 } [[AGG_LEFT]], 1
; CHECK-NEXT: call void @foo()
; CHECK-NEXT: br label [[MERGE:%.*]]
; CHECK: right:
-; CHECK-NEXT: [[I3:%.*]] = extractvalue { i32, i32 } [[AGG_RIGHT:%.*]], 0
-; CHECK-NEXT: [[I4:%.*]] = extractvalue { i32, i32 } [[AGG_RIGHT]], 1
; CHECK-NEXT: call void @bar()
; CHECK-NEXT: br label [[MERGE]]
; CHECK: merge:
-; CHECK-NEXT: [[I5:%.*]] = phi i32 [ [[I0]], [[LEFT]] ], [ [[I3]], [[RIGHT]] ]
-; CHECK-NEXT: [[I6:%.*]] = phi i32 [ [[I2]], [[LEFT]] ], [ [[I4]], [[RIGHT]] ]
+; CHECK-NEXT: [[I8_MERGED:%.*]] = phi { i32, i32 } [ [[AGG_RIGHT:%.*]], [[RIGHT]] ], [ [[AGG_LEFT:%.*]], [[LEFT]] ]
; CHECK-NEXT: call void @baz()
; CHECK-NEXT: br i1 [[C1:%.*]], label [[END:%.*]], label [[PASSTHROUGH:%.*]]
; CHECK: passthrough:
; CHECK-NEXT: br label [[END]]
; CHECK: end:
; CHECK-NEXT: call void @quux()
-; CHECK-NEXT: [[I7:%.*]] = insertvalue { i32, i32 } undef, i32 [[I5]], 0
-; CHECK-NEXT: [[I8:%.*]] = insertvalue { i32, i32 } [[I7]], i32 [[I6]], 1
-; CHECK-NEXT: ret { i32, i32 } [[I8]]
+; CHECK-NEXT: ret { i32, i32 } [[I8_MERGED]]
;
entry:
br i1 %c0, label %left, label %right