diff --git a/llvm/include/llvm/Analysis/MemoryLocation.h b/llvm/include/llvm/Analysis/MemoryLocation.h --- a/llvm/include/llvm/Analysis/MemoryLocation.h +++ b/llvm/include/llvm/Analysis/MemoryLocation.h @@ -145,6 +145,8 @@ return (Value & ImpreciseBit) == 0; } + void setToUnknown() { Value = Unknown; } + // Convenience method to check if this LocationSize's value is 0. bool isZero() const { return hasValue() && getValue() == 0; } @@ -205,6 +207,10 @@ /// member is null if that kind of information is unavailable). AAMDNodes AATags; + void print(raw_ostream &OS) const { OS << *Ptr << " " << Size << "\n"; } + + void setSizeToUnknown() { Size.setToUnknown(); } + /// Return a location with information about the memory reference by the given /// instruction. static MemoryLocation get(const LoadInst *LI); diff --git a/llvm/include/llvm/Analysis/MemorySSA.h b/llvm/include/llvm/Analysis/MemorySSA.h --- a/llvm/include/llvm/Analysis/MemorySSA.h +++ b/llvm/include/llvm/Analysis/MemorySSA.h @@ -1228,6 +1228,8 @@ CurrentPair.second = Location.getWithNewPtr(Translator.getAddr()); return; } + } else { + Location.setSizeToUnknown(); } } CurrentPair.second = Location; diff --git a/llvm/test/Analysis/MemorySSA/phi-translation.ll b/llvm/test/Analysis/MemorySSA/phi-translation.ll --- a/llvm/test/Analysis/MemorySSA/phi-translation.ll +++ b/llvm/test/Analysis/MemorySSA/phi-translation.ll @@ -235,3 +235,55 @@ %m_i_size.1 = phi i32 [ %m_i_size.022, %if.then ], [ %mul, %for.body ] br i1 %cmp1, label %for.body, label %for.cond.cleanup } + + +%ArrayType = type { [2 x i64] } +%StructOverArrayType = type { %ArrayType } +%BigStruct = type { i8, i8, i8, i8, i8, i8, i8, %ArrayType, %ArrayType} + +; CHECK-LABEL: define void @use_not_optimized_due_to_backedge_unknown +define void @use_not_optimized_due_to_backedge_unknown(%BigStruct* %this) { +entry: + %eval_left_dims = alloca %StructOverArrayType, align 8 + %tmp0 = bitcast %StructOverArrayType* %eval_left_dims to i8* + %eval_right_dims = alloca %StructOverArrayType, align 8 + %tmp1 = bitcast %StructOverArrayType* %eval_right_dims to i8* + %lhs_strides = alloca %ArrayType, align 8 + %rhs_strides = alloca %ArrayType, align 8 + br label %for.body.preheader + +for.body.preheader: ; preds = %entry + %arrayidx.i527 = getelementptr inbounds %BigStruct, %BigStruct* %this, i64 0, i32 7, i32 0, i64 0 +; CHECK: 1 = MemoryDef(liveOnEntry) +; CHECK-NEXT: store i64 1, i64* %arrayidx.i527, align 8 + store i64 1, i64* %arrayidx.i527, align 8 + %arrayidx.i528 = getelementptr inbounds %BigStruct, %BigStruct* %this, i64 0, i32 8, i32 0, i64 0 +; CHECK: 2 = MemoryDef(1) +; CHECK-NEXT: store i64 1, i64* %arrayidx.i528, align 8 + store i64 1, i64* %arrayidx.i528, align 8 + br label %for.main.body + +for.main.body: ; preds = %if.end220.if.then185_crit_edge, %for.body.preheader +; CHECK: 4 = MemoryPhi({for.body.preheader,2},{if.end220.if.then185_crit_edge,3}) +; CHECK-NEXT: %nocontract_idx.0656 = phi i64 [ 0, %for.body.preheader ], [ 1, %if.end220.if.then185_crit_edge ] + %nocontract_idx.0656 = phi i64 [ 0, %for.body.preheader ], [ 1, %if.end220.if.then185_crit_edge ] + %add199 = add nuw nsw i64 %nocontract_idx.0656, 1 + %cmp200 = icmp eq i64 %nocontract_idx.0656, 0 + %arrayidx.i559 = getelementptr inbounds %BigStruct, %BigStruct* %this, i64 0, i32 7, i32 0, i64 %nocontract_idx.0656 +; CHECK: MemoryUse(4) MayAlias +; CHECK-NEXT: %tmp21 = load i64, i64* %arrayidx.i559, align 8 + %tmp21 = load i64, i64* %arrayidx.i559, align 8 + %mul206 = mul nsw i64 %tmp21, %tmp21 + br i1 %cmp200, label %if.end220.if.then185_crit_edge, label %the.end + +if.end220.if.then185_crit_edge: ; preds = %for.main.body + %arrayidx.i571 = getelementptr inbounds %BigStruct, %BigStruct* %this, i64 0, i32 7, i32 0, i64 %add199 +; CHECK: 3 = MemoryDef(4) +; CHECK-NEXT: store i64 %mul206, i64* %arrayidx.i571, align 8 + store i64 %mul206, i64* %arrayidx.i571, align 8 + br label %for.main.body + +the.end: ; preds = %for.main.body + ret void + +}