forked from OSchip/llvm-project
[Instcombine] Disable memcpy of alloca bypass for instruction sources
This transformation is fundamentally broken when it comes to dominance,
it just happened to work when the source of the memcpy can be moved into
the place of the alloca. The bug shows up a lot more often since
077bff39d4
allows the source to be a
switch.
It would be possible to check dominance of the source and all its
operands, but that seems very heavy for instcombine.
This commit is contained in:
parent
e3070db0f7
commit
cf4161673c
|
@ -407,10 +407,9 @@ Instruction *InstCombinerImpl::visitAllocaInst(AllocaInst &AI) {
|
|||
TheSrc, AllocaAlign, DL, &AI, &AC, &DT);
|
||||
if (AllocaAlign <= SourceAlign &&
|
||||
isDereferenceableForAllocaSize(TheSrc, &AI, DL) &&
|
||||
(!isa<Instruction>(TheSrc) || all_of(AI.users(), [&](const User *U) {
|
||||
return DT.dominates(cast<Instruction>(TheSrc), cast<Instruction>(U));
|
||||
}))) {
|
||||
// FIXME: can the dominance restriction be relaxed by sinking instrns?
|
||||
!isa<Instruction>(TheSrc)) {
|
||||
// FIXME: Can we sink instructions without violating dominance when TheSrc
|
||||
// is an instruction instead of a constant or argument?
|
||||
LLVM_DEBUG(dbgs() << "Found alloca equal to global: " << AI << '\n');
|
||||
LLVM_DEBUG(dbgs() << " memcpy = " << *Copy << '\n');
|
||||
unsigned SrcAddrSpace = TheSrc->getType()->getPointerAddressSpace();
|
||||
|
|
|
@ -31,5 +31,29 @@ define void @test(i8*%out) {
|
|||
ret void
|
||||
}
|
||||
|
||||
define void @test2() {
|
||||
; CHECK-LABEL: @test2(
|
||||
; CHECK-NEXT: bb:
|
||||
; CHECK-NEXT: [[I:%.*]] = alloca [[T0:%.*]], align 8
|
||||
; CHECK-NEXT: [[I1:%.*]] = call i32 @func(%t0* undef)
|
||||
; CHECK-NEXT: [[I2:%.*]] = icmp eq i32 [[I1]], 2503
|
||||
; CHECK-NEXT: [[I3:%.*]] = select i1 [[I2]], i8* bitcast (%t0* @g0 to i8*), i8* bitcast (%t0* @g1 to i8*)
|
||||
; CHECK-NEXT: [[I4:%.*]] = bitcast %t0* [[I]] to i8*
|
||||
; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* noundef nonnull align 8 dereferenceable(16) [[I4]], i8* noundef nonnull align 8 dereferenceable(16) [[I3]], i64 16, i1 false)
|
||||
; CHECK-NEXT: [[I5:%.*]] = call i32 @func(%t0* nonnull byval([[T0]]) [[I]])
|
||||
; CHECK-NEXT: unreachable
|
||||
;
|
||||
bb:
|
||||
%i = alloca %t0, align 8
|
||||
%i1 = call i32 @func(%t0* undef)
|
||||
%i2 = icmp eq i32 %i1, 2503
|
||||
%i3 = select i1 %i2, i8* bitcast (%t0* @g0 to i8*), i8* bitcast (%t0* @g1 to i8*)
|
||||
%i4 = bitcast %t0* %i to i8*
|
||||
call void @llvm.memcpy.p0i8.p0i8.i64(i8* noundef nonnull align 8 dereferenceable(16) %i4, i8* noundef nonnull align 8 dereferenceable(16) %i3, i64 16, i1 false)
|
||||
%i5 = call i32 @func(%t0* nonnull byval(%t0) %i)
|
||||
unreachable
|
||||
}
|
||||
|
||||
declare i32 @func(%t0*)
|
||||
declare i1 @get_cond()
|
||||
declare void @llvm.memcpy.p0i8.p0i8.i64(i8*, i8*, i64, i1)
|
||||
|
|
Loading…
Reference in New Issue