[Attributor] Try to delete stores and simplify stored values

By default we should try to eliminate unused stores and simplify values
stored while we are at it.
This commit is contained in:
Johannes Doerfert 2022-05-19 13:51:07 -05:00
parent a3273c0c06
commit 94841c713f
7 changed files with 39 additions and 55 deletions

View File

@ -2874,7 +2874,8 @@ void Attributor::identifyDefaultAbstractAttributes(Function &F) {
getOrCreateAAFor<AAIsDead>(RetPos);
// Every function might be simplified.
getOrCreateAAFor<AAValueSimplify>(RetPos);
bool UsedAssumedInformation = false;
getAssumedSimplified(RetPos, nullptr, UsedAssumedInformation);
// Every returned value might be marked noundef.
getOrCreateAAFor<AANoUndef>(RetPos);
@ -2966,7 +2967,8 @@ void Attributor::identifyDefaultAbstractAttributes(Function &F) {
if (!Callee->getReturnType()->isVoidTy() && !CB.use_empty()) {
IRPosition CBRetPos = IRPosition::callsite_returned(CB);
getOrCreateAAFor<AAValueSimplify>(CBRetPos);
bool UsedAssumedInformation = false;
getAssumedSimplified(CBRetPos, nullptr, UsedAssumedInformation);
}
for (int I = 0, E = CB.arg_size(); I < E; ++I) {
@ -3029,10 +3031,15 @@ void Attributor::identifyDefaultAbstractAttributes(Function &F) {
getOrCreateAAFor<AAAlign>(
IRPosition::value(*cast<LoadInst>(I).getPointerOperand()));
if (SimplifyAllLoads)
getOrCreateAAFor<AAValueSimplify>(IRPosition::value(I));
} else
getOrCreateAAFor<AAAlign>(
IRPosition::value(*cast<StoreInst>(I).getPointerOperand()));
getAssumedSimplified(IRPosition::value(I), nullptr,
UsedAssumedInformation);
} else {
auto &SI = cast<StoreInst>(I);
getOrCreateAAFor<AAIsDead>(IRPosition::inst(I));
getAssumedSimplified(IRPosition::value(*SI.getValueOperand()), nullptr,
UsedAssumedInformation);
getOrCreateAAFor<AAAlign>(IRPosition::value(*SI.getPointerOperand()));
}
return true;
};
Success = checkForAllInstructionsImpl(

View File

@ -645,7 +645,6 @@ define i32 @malloc_in_loop(i32 %0) {
; IS________OPM: 8:
; IS________OPM-NEXT: [[TMP9:%.*]] = call noalias i8* @malloc(i64 noundef 4)
; IS________OPM-NEXT: [[TMP10:%.*]] = bitcast i8* [[TMP9]] to i32*
; IS________OPM-NEXT: store i32 1, i32* [[TMP10]], align 8
; IS________OPM-NEXT: br label [[TMP4]]
; IS________OPM: 11:
; IS________OPM-NEXT: ret i32 5

View File

@ -498,7 +498,6 @@ define i32 @malloc_in_loop(i32 %0) {
; CHECK: 8:
; CHECK-NEXT: [[TMP9:%.*]] = call noalias i8* @malloc(i64 noundef 4)
; CHECK-NEXT: [[TMP10:%.*]] = bitcast i8* [[TMP9]] to i32*
; CHECK-NEXT: store i32 1, i32* [[TMP10]], align 8
; CHECK-NEXT: br label [[TMP4]]
; CHECK: 11:
; CHECK-NEXT: ret i32 5

View File

@ -214,10 +214,10 @@ define i32 @nc1(i32* %q, i32* %p, i1 %b) {
; IS__TUNIT____-NEXT: br label [[L:%.*]]
; IS__TUNIT____: l:
; IS__TUNIT____-NEXT: [[Y:%.*]] = phi i32* [ [[Q]], [[E:%.*]] ]
; IS__TUNIT____-NEXT: [[TMP2:%.*]] = select i1 [[B]], i32* [[P]], i32* [[Y]]
; IS__TUNIT____-NEXT: [[TMP2:%.*]] = select i1 [[B]], i32* [[P]], i32* [[Q]]
; IS__TUNIT____-NEXT: [[VAL:%.*]] = load i32, i32* [[TMP2]], align 4
; IS__TUNIT____-NEXT: store i32 0, i32* [[P]], align 4
; IS__TUNIT____-NEXT: store i32* [[Y]], i32** @g, align 8
; IS__TUNIT____-NEXT: store i32* [[Q]], i32** @g, align 8
; IS__TUNIT____-NEXT: ret i32 [[VAL]]
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn
@ -227,10 +227,10 @@ define i32 @nc1(i32* %q, i32* %p, i1 %b) {
; IS__CGSCC____-NEXT: br label [[L:%.*]]
; IS__CGSCC____: l:
; IS__CGSCC____-NEXT: [[Y:%.*]] = phi i32* [ [[Q]], [[E:%.*]] ]
; IS__CGSCC____-NEXT: [[TMP2:%.*]] = select i1 [[B]], i32* [[P]], i32* [[Y]]
; IS__CGSCC____-NEXT: [[TMP2:%.*]] = select i1 [[B]], i32* [[P]], i32* [[Q]]
; IS__CGSCC____-NEXT: [[VAL:%.*]] = load i32, i32* [[TMP2]], align 4
; IS__CGSCC____-NEXT: store i32 0, i32* [[P]], align 4
; IS__CGSCC____-NEXT: store i32* [[Y]], i32** @g, align 8
; IS__CGSCC____-NEXT: store i32* [[Q]], i32** @g, align 8
; IS__CGSCC____-NEXT: ret i32 [[VAL]]
;
e:
@ -256,10 +256,10 @@ define i32 @nc1_addrspace(i32* %q, i32 addrspace(1)* %p, i1 %b) {
; IS__TUNIT____-NEXT: [[X:%.*]] = phi i32 addrspace(1)* [ [[P]], [[E:%.*]] ]
; IS__TUNIT____-NEXT: [[Y:%.*]] = phi i32* [ [[Q]], [[E]] ]
; IS__TUNIT____-NEXT: [[TMP:%.*]] = addrspacecast i32 addrspace(1)* [[X]] to i32*
; IS__TUNIT____-NEXT: [[TMP2:%.*]] = select i1 [[B]], i32* [[TMP]], i32* [[Y]]
; IS__TUNIT____-NEXT: [[TMP2:%.*]] = select i1 [[B]], i32* [[TMP]], i32* [[Q]]
; IS__TUNIT____-NEXT: [[VAL:%.*]] = load i32, i32* [[TMP2]], align 4
; IS__TUNIT____-NEXT: store i32 0, i32* [[TMP]], align 4
; IS__TUNIT____-NEXT: store i32* [[Y]], i32** @g, align 8
; IS__TUNIT____-NEXT: store i32* [[Q]], i32** @g, align 8
; IS__TUNIT____-NEXT: ret i32 [[VAL]]
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn
@ -271,10 +271,10 @@ define i32 @nc1_addrspace(i32* %q, i32 addrspace(1)* %p, i1 %b) {
; IS__CGSCC____-NEXT: [[X:%.*]] = phi i32 addrspace(1)* [ [[P]], [[E:%.*]] ]
; IS__CGSCC____-NEXT: [[Y:%.*]] = phi i32* [ [[Q]], [[E]] ]
; IS__CGSCC____-NEXT: [[TMP:%.*]] = addrspacecast i32 addrspace(1)* [[X]] to i32*
; IS__CGSCC____-NEXT: [[TMP2:%.*]] = select i1 [[B]], i32* [[TMP]], i32* [[Y]]
; IS__CGSCC____-NEXT: [[TMP2:%.*]] = select i1 [[B]], i32* [[TMP]], i32* [[Q]]
; IS__CGSCC____-NEXT: [[VAL:%.*]] = load i32, i32* [[TMP2]], align 4
; IS__CGSCC____-NEXT: store i32 0, i32* [[TMP]], align 4
; IS__CGSCC____-NEXT: store i32* [[Y]], i32** @g, align 8
; IS__CGSCC____-NEXT: store i32* [[Q]], i32** @g, align 8
; IS__CGSCC____-NEXT: ret i32 [[VAL]]
;
e:

View File

@ -121,20 +121,16 @@ define void @local_alloca_simplifiable_1(%struct.S* noalias sret(%struct.S) alig
; IS__TUNIT_OPM-NEXT: call void @write_arg(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(16) [[I3]], i32 noundef 3) #[[ATTR14]]
; IS__TUNIT_OPM-NEXT: [[F12:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 3
; IS__TUNIT_OPM-NEXT: store float 0x3FF19999A0000000, float* [[F12]], align 4, !tbaa [[TBAA7:![0-9]+]]
; IS__TUNIT_OPM-NEXT: [[MUL:%.*]] = fmul float 0x40019999A0000000, 2.000000e+00
; IS__TUNIT_OPM-NEXT: [[F24:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 4
; IS__TUNIT_OPM-NEXT: store float [[MUL]], float* [[F24]], align 4, !tbaa [[TBAA10:![0-9]+]]
; IS__TUNIT_OPM-NEXT: [[ADD:%.*]] = fadd float 0x400A666660000000, 0x3FF19999A0000000
; IS__TUNIT_OPM-NEXT: store float 0x40119999A0000000, float* [[F24]], align 4, !tbaa [[TBAA10:![0-9]+]]
; IS__TUNIT_OPM-NEXT: [[F37:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 5
; IS__TUNIT_OPM-NEXT: store float [[ADD]], float* [[F37]], align 4, !tbaa [[TBAA11:![0-9]+]]
; IS__TUNIT_OPM-NEXT: store float 0x40119999A0000000, float* [[F37]], align 4, !tbaa [[TBAA11:![0-9]+]]
; IS__TUNIT_OPM-NEXT: [[I19:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 0
; IS__TUNIT_OPM-NEXT: store i32 1, i32* [[I19]], align 4, !tbaa [[TBAA12:![0-9]+]]
; IS__TUNIT_OPM-NEXT: [[MUL11:%.*]] = shl nsw i32 2, 1
; IS__TUNIT_OPM-NEXT: [[I212:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 1
; IS__TUNIT_OPM-NEXT: store i32 [[MUL11]], i32* [[I212]], align 4, !tbaa [[TBAA13:![0-9]+]]
; IS__TUNIT_OPM-NEXT: [[ADD15:%.*]] = add nsw i32 3, 1
; IS__TUNIT_OPM-NEXT: store i32 4, i32* [[I212]], align 4, !tbaa [[TBAA13:![0-9]+]]
; IS__TUNIT_OPM-NEXT: [[I316:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 2
; IS__TUNIT_OPM-NEXT: store i32 [[ADD15]], i32* [[I316]], align 4, !tbaa [[TBAA14:![0-9]+]]
; IS__TUNIT_OPM-NEXT: store i32 4, i32* [[I316]], align 4, !tbaa [[TBAA14:![0-9]+]]
; IS__TUNIT_OPM-NEXT: [[I12:%.*]] = bitcast %struct.S* [[S]] to i8*
; IS__TUNIT_OPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 24, i8* nocapture nofree noundef nonnull align 4 dereferenceable(24) [[I12]]) #[[ATTR13]]
; IS__TUNIT_OPM-NEXT: ret void
@ -157,20 +153,16 @@ define void @local_alloca_simplifiable_1(%struct.S* noalias sret(%struct.S) alig
; IS__TUNIT_NPM-NEXT: call void @write_arg(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(16) [[I3]], i32 noundef 3) #[[ATTR13]]
; IS__TUNIT_NPM-NEXT: [[F12:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 3
; IS__TUNIT_NPM-NEXT: store float 0x3FF19999A0000000, float* [[F12]], align 4, !tbaa [[TBAA7:![0-9]+]]
; IS__TUNIT_NPM-NEXT: [[MUL:%.*]] = fmul float 0x40019999A0000000, 2.000000e+00
; IS__TUNIT_NPM-NEXT: [[F24:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 4
; IS__TUNIT_NPM-NEXT: store float [[MUL]], float* [[F24]], align 4, !tbaa [[TBAA10:![0-9]+]]
; IS__TUNIT_NPM-NEXT: [[ADD:%.*]] = fadd float 0x400A666660000000, 0x3FF19999A0000000
; IS__TUNIT_NPM-NEXT: store float 0x40119999A0000000, float* [[F24]], align 4, !tbaa [[TBAA10:![0-9]+]]
; IS__TUNIT_NPM-NEXT: [[F37:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 5
; IS__TUNIT_NPM-NEXT: store float [[ADD]], float* [[F37]], align 4, !tbaa [[TBAA11:![0-9]+]]
; IS__TUNIT_NPM-NEXT: store float 0x40119999A0000000, float* [[F37]], align 4, !tbaa [[TBAA11:![0-9]+]]
; IS__TUNIT_NPM-NEXT: [[I19:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 0
; IS__TUNIT_NPM-NEXT: store i32 1, i32* [[I19]], align 4, !tbaa [[TBAA12:![0-9]+]]
; IS__TUNIT_NPM-NEXT: [[MUL11:%.*]] = shl nsw i32 2, 1
; IS__TUNIT_NPM-NEXT: [[I212:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 1
; IS__TUNIT_NPM-NEXT: store i32 [[MUL11]], i32* [[I212]], align 4, !tbaa [[TBAA13:![0-9]+]]
; IS__TUNIT_NPM-NEXT: [[ADD15:%.*]] = add nsw i32 3, 1
; IS__TUNIT_NPM-NEXT: store i32 4, i32* [[I212]], align 4, !tbaa [[TBAA13:![0-9]+]]
; IS__TUNIT_NPM-NEXT: [[I316:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 2
; IS__TUNIT_NPM-NEXT: store i32 [[ADD15]], i32* [[I316]], align 4, !tbaa [[TBAA14:![0-9]+]]
; IS__TUNIT_NPM-NEXT: store i32 4, i32* [[I316]], align 4, !tbaa [[TBAA14:![0-9]+]]
; IS__TUNIT_NPM-NEXT: [[I12:%.*]] = bitcast %struct.S* [[S]] to i8*
; IS__TUNIT_NPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 24, i8* nocapture nofree noundef nonnull align 4 dereferenceable(24) [[I12]]) #[[ATTR12]]
; IS__TUNIT_NPM-NEXT: ret void
@ -1089,20 +1081,16 @@ define void @static_global_simplifiable_1(%struct.S* noalias sret(%struct.S) ali
; IS__TUNIT_OPM-NEXT: call void @write_arg(i32* nocapture nofree writeonly align 4 dereferenceable_or_null(16) getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i64 0, i32 2), i32 noundef 3) #[[ATTR14]]
; IS__TUNIT_OPM-NEXT: [[F1:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 3
; IS__TUNIT_OPM-NEXT: store float 0x3FF19999A0000000, float* [[F1]], align 4, !tbaa [[TBAA7]]
; IS__TUNIT_OPM-NEXT: [[MUL:%.*]] = fmul float 0x40019999A0000000, 2.000000e+00
; IS__TUNIT_OPM-NEXT: [[F2:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 4
; IS__TUNIT_OPM-NEXT: store float [[MUL]], float* [[F2]], align 4, !tbaa [[TBAA10]]
; IS__TUNIT_OPM-NEXT: [[ADD:%.*]] = fadd float 0x400A666660000000, 0x3FF19999A0000000
; IS__TUNIT_OPM-NEXT: store float 0x40119999A0000000, float* [[F2]], align 4, !tbaa [[TBAA10]]
; IS__TUNIT_OPM-NEXT: [[F3:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 5
; IS__TUNIT_OPM-NEXT: store float [[ADD]], float* [[F3]], align 4, !tbaa [[TBAA11]]
; IS__TUNIT_OPM-NEXT: store float 0x40119999A0000000, float* [[F3]], align 4, !tbaa [[TBAA11]]
; IS__TUNIT_OPM-NEXT: [[I1:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 0
; IS__TUNIT_OPM-NEXT: store i32 1, i32* [[I1]], align 4, !tbaa [[TBAA12]]
; IS__TUNIT_OPM-NEXT: [[MUL1:%.*]] = shl nsw i32 2, 1
; IS__TUNIT_OPM-NEXT: [[I2:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 1
; IS__TUNIT_OPM-NEXT: store i32 [[MUL1]], i32* [[I2]], align 4, !tbaa [[TBAA13]]
; IS__TUNIT_OPM-NEXT: [[ADD2:%.*]] = add nsw i32 3, 1
; IS__TUNIT_OPM-NEXT: store i32 4, i32* [[I2]], align 4, !tbaa [[TBAA13]]
; IS__TUNIT_OPM-NEXT: [[I3:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 2
; IS__TUNIT_OPM-NEXT: store i32 [[ADD2]], i32* [[I3]], align 4, !tbaa [[TBAA14]]
; IS__TUNIT_OPM-NEXT: store i32 4, i32* [[I3]], align 4, !tbaa [[TBAA14]]
; IS__TUNIT_OPM-NEXT: ret void
;
; IS__TUNIT_NPM: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly
@ -1114,20 +1102,16 @@ define void @static_global_simplifiable_1(%struct.S* noalias sret(%struct.S) ali
; IS__TUNIT_NPM-NEXT: call void @write_arg(i32* nocapture nofree writeonly align 4 dereferenceable_or_null(16) getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i64 0, i32 2), i32 noundef 3) #[[ATTR13]]
; IS__TUNIT_NPM-NEXT: [[F1:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 3
; IS__TUNIT_NPM-NEXT: store float 0x3FF19999A0000000, float* [[F1]], align 4, !tbaa [[TBAA7]]
; IS__TUNIT_NPM-NEXT: [[MUL:%.*]] = fmul float 0x40019999A0000000, 2.000000e+00
; IS__TUNIT_NPM-NEXT: [[F2:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 4
; IS__TUNIT_NPM-NEXT: store float [[MUL]], float* [[F2]], align 4, !tbaa [[TBAA10]]
; IS__TUNIT_NPM-NEXT: [[ADD:%.*]] = fadd float 0x400A666660000000, 0x3FF19999A0000000
; IS__TUNIT_NPM-NEXT: store float 0x40119999A0000000, float* [[F2]], align 4, !tbaa [[TBAA10]]
; IS__TUNIT_NPM-NEXT: [[F3:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 5
; IS__TUNIT_NPM-NEXT: store float [[ADD]], float* [[F3]], align 4, !tbaa [[TBAA11]]
; IS__TUNIT_NPM-NEXT: store float 0x40119999A0000000, float* [[F3]], align 4, !tbaa [[TBAA11]]
; IS__TUNIT_NPM-NEXT: [[I1:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 0
; IS__TUNIT_NPM-NEXT: store i32 1, i32* [[I1]], align 4, !tbaa [[TBAA12]]
; IS__TUNIT_NPM-NEXT: [[MUL1:%.*]] = shl nsw i32 2, 1
; IS__TUNIT_NPM-NEXT: [[I2:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 1
; IS__TUNIT_NPM-NEXT: store i32 [[MUL1]], i32* [[I2]], align 4, !tbaa [[TBAA13]]
; IS__TUNIT_NPM-NEXT: [[ADD2:%.*]] = add nsw i32 3, 1
; IS__TUNIT_NPM-NEXT: store i32 4, i32* [[I2]], align 4, !tbaa [[TBAA13]]
; IS__TUNIT_NPM-NEXT: [[I3:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 2
; IS__TUNIT_NPM-NEXT: store i32 [[ADD2]], i32* [[I3]], align 4, !tbaa [[TBAA14]]
; IS__TUNIT_NPM-NEXT: store i32 4, i32* [[I3]], align 4, !tbaa [[TBAA14]]
; IS__TUNIT_NPM-NEXT: ret void
;
; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind willreturn
@ -2681,7 +2665,6 @@ define i32 @static_global_not_simplifiable_1(i32 %cnd) {
; CHECK-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[CND]], 0
; CHECK-NEXT: br i1 [[TOBOOL_NOT]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
; CHECK: if.then:
; CHECK-NEXT: store i32 1, i32* @Flag1, align 4, !tbaa [[TBAA3]]
; CHECK-NEXT: br label [[IF_END]]
; CHECK: if.end:
; CHECK-NEXT: ret i32 1

View File

@ -1229,16 +1229,14 @@ define internal void @f1(i8*** %a) {
; IS__TUNIT____-LABEL: define {{[^@]+}}@f1
; IS__TUNIT____-SAME: (i8*** nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[A:%.*]]) #[[ATTR3]] {
; IS__TUNIT____-NEXT: entry:
; IS__TUNIT____-NEXT: [[X:%.*]] = getelementptr { [2 x i8*] }, { [2 x i8*] }* @g, i32 0, i32 0, i32 0
; IS__TUNIT____-NEXT: store i8** [[X]], i8*** [[A]], align 8
; IS__TUNIT____-NEXT: store i8** getelementptr inbounds ({ [2 x i8*] }, { [2 x i8*] }* @g, i32 0, i32 0, i32 0), i8*** [[A]], align 8
; IS__TUNIT____-NEXT: ret void
;
; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
; IS__CGSCC____-LABEL: define {{[^@]+}}@f1
; IS__CGSCC____-SAME: (i8*** nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[A:%.*]]) #[[ATTR4]] {
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: [[X:%.*]] = getelementptr { [2 x i8*] }, { [2 x i8*] }* @g, i32 0, i32 0, i32 0
; IS__CGSCC____-NEXT: store i8** [[X]], i8*** [[A]], align 8
; IS__CGSCC____-NEXT: store i8** getelementptr inbounds ({ [2 x i8*] }, { [2 x i8*] }* @g, i32 0, i32 0, i32 0), i8*** [[A]], align 8
; IS__CGSCC____-NEXT: ret void
;
entry:

View File

@ -5181,7 +5181,6 @@ entry:
; CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* noundef nonnull [[TMP4]])
; CHECK1-NEXT: [[TMP5:%.*]] = ptrtoint i32* [[B]] to i64
; CHECK1-NEXT: [[TMP6:%.*]] = trunc i64 [[TMP5]] to i32
; CHECK1-NEXT: store i32 [[TMP6]], i32* [[B]], align 4
; CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* noundef nonnull [[TMP4]])
; CHECK1-NEXT: br label [[OMP_PAR_MERGED_SPLIT:%.*]]
; CHECK1: omp.par.merged.split:
@ -6397,7 +6396,6 @@ entry:
; CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* noundef nonnull [[TMP4]])
; CHECK2-NEXT: [[TMP5:%.*]] = ptrtoint i32* [[B]] to i64
; CHECK2-NEXT: [[TMP6:%.*]] = trunc i64 [[TMP5]] to i32
; CHECK2-NEXT: store i32 [[TMP6]], i32* [[B]], align 4
; CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* noundef nonnull [[TMP4]])
; CHECK2-NEXT: br label [[OMP_PAR_MERGED_SPLIT:%.*]]
; CHECK2: omp.par.merged.split: