cast<Instruction>(cast<StoreInst>(OtherInst)->getValueOperand());
ClonedVal->intersectOptionalDataWith(OtherVal);
}
- ClonedVal->clearSubclassOptionalData();
Repl->replaceUsesOfWith(Val, ClonedVal);
}
for (Instruction *I : InstructionsToHoist)
if (I != Repl) {
++NR;
- if (isa<LoadInst>(Repl))
+ if (auto *ReplacementLoad = dyn_cast<LoadInst>(Repl)) {
+ ReplacementLoad->setAlignment(
+ std::min(ReplacementLoad->getAlignment(),
+ cast<LoadInst>(I)->getAlignment()));
++NumLoadsRemoved;
- else if (isa<StoreInst>(Repl))
+ } else if (auto *ReplacementStore = dyn_cast<StoreInst>(Repl)) {
+ ReplacementStore->setAlignment(
+ std::min(ReplacementStore->getAlignment(),
+ cast<StoreInst>(I)->getAlignment()));
++NumStoresRemoved;
- else if (isa<CallInst>(Repl))
+ } else if (auto *ReplacementAlloca = dyn_cast<AllocaInst>(Repl)) {
+ ReplacementAlloca->setAlignment(
+ std::max(ReplacementAlloca->getAlignment(),
+ cast<AllocaInst>(I)->getAlignment()));
+ } else if (isa<CallInst>(Repl)) {
++NumCallsRemoved;
+ }
Repl->intersectOptionalDataWith(I);
I->replaceAllUsesWith(Repl);
I->eraseFromParent();
if.end: ; preds = %if.else, %if.then
ret void
}
+
+define i32 @mergeAlignments(i1 %b, i32* %y) {
+entry:
+ br i1 %b, label %if.then, label %if.end
+
+if.then: ; preds = %entry
+ %l1 = load i32, i32* %y, align 4
+ br label %return
+
+if.end: ; preds = %entry
+ %l2 = load i32, i32* %y, align 1
+ br label %return
+
+return: ; preds = %if.end, %if.then
+ %retval.0 = phi i32 [ %l1, %if.then ], [ %l2, %if.end ]
+ ret i32 %retval.0
+}
+; CHECK-LABEL: define i32 @mergeAlignments(
+; CHECK: %[[load:.*]] = load i32, i32* %y, align 1
+; CHECK: %[[phi:.*]] = phi i32 [ %[[load]], %{{.*}} ], [ %[[load]], %{{.*}} ]
+; CHECK: i32 %[[phi]]