forked from OSchip/llvm-project
				
			[ObjCARC] Do not move a release that has the clang.imprecise_release tag
above PHI instructions. ARC optimizer has an optimization that moves a call to an ObjC runtime function above a phi instruction when the phi has a null operand and is an argument passed to the function call. This optimization should not kick in when the runtime function is an objc_release that releases an object with precise lifetime semantics. rdar://problem/34959669 llvm-svn: 315914
This commit is contained in:
		
							parent
							
								
									a4b89ed0b7
								
							
						
					
					
						commit
						e8c1a54c07
					
				| 
						 | 
					@ -808,9 +808,14 @@ void ObjCARCOpt::OptimizeIndividualCalls(Function &F) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // If Arg is a PHI, and one or more incoming values to the
 | 
					    // If Arg is a PHI, and one or more incoming values to the
 | 
				
			||||||
    // PHI are null, and the call is control-equivalent to the PHI, and there
 | 
					    // PHI are null, and the call is control-equivalent to the PHI, and there
 | 
				
			||||||
    // are no relevant side effects between the PHI and the call, the call
 | 
					    // are no relevant side effects between the PHI and the call, and the call
 | 
				
			||||||
    // could be pushed up to just those paths with non-null incoming values.
 | 
					    // is not a release that doesn't have the clang.imprecise_release tag, the
 | 
				
			||||||
    // For now, don't bother splitting critical edges for this.
 | 
					    // call could be pushed up to just those paths with non-null incoming
 | 
				
			||||||
 | 
					    // values. For now, don't bother splitting critical edges for this.
 | 
				
			||||||
 | 
					    if (Class == ARCInstKind::Release &&
 | 
				
			||||||
 | 
					        !Inst->getMetadata(MDKindCache.get(ARCMDKindID::ImpreciseRelease)))
 | 
				
			||||||
 | 
					      continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    SmallVector<std::pair<Instruction *, const Value *>, 4> Worklist;
 | 
					    SmallVector<std::pair<Instruction *, const Value *>, 4> Worklist;
 | 
				
			||||||
    Worklist.push_back(std::make_pair(Inst, Arg));
 | 
					    Worklist.push_back(std::make_pair(Inst, Arg));
 | 
				
			||||||
    do {
 | 
					    do {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1342,6 +1342,26 @@ A:
 | 
				
			||||||
  br label %C
 | 
					  br label %C
 | 
				
			||||||
B:
 | 
					B:
 | 
				
			||||||
  br label %C
 | 
					  br label %C
 | 
				
			||||||
 | 
					C:
 | 
				
			||||||
 | 
					  %h = phi double* [ null, %A ], [ %p, %B ]
 | 
				
			||||||
 | 
					  %c = bitcast double* %h to i8*
 | 
				
			||||||
 | 
					  call void @objc_release(i8* %c), !clang.imprecise_release !0
 | 
				
			||||||
 | 
					  ret void
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					; Do not move an objc_release that doesn't have the clang.imprecise_release tag.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					; CHECK-LABEL: define void @test22_precise(
 | 
				
			||||||
 | 
					; CHECK: %[[P0:.*]] = phi double*
 | 
				
			||||||
 | 
					; CHECK: %[[V0:.*]] = bitcast double* %[[P0]] to i8*
 | 
				
			||||||
 | 
					; CHECK: call void @objc_release(i8* %[[V0]])
 | 
				
			||||||
 | 
					; CHECK: ret void
 | 
				
			||||||
 | 
					define void @test22_precise(double* %p, i1 %a) {
 | 
				
			||||||
 | 
					  br i1 %a, label %A, label %B
 | 
				
			||||||
 | 
					A:
 | 
				
			||||||
 | 
					  br label %C
 | 
				
			||||||
 | 
					B:
 | 
				
			||||||
 | 
					  br label %C
 | 
				
			||||||
C:
 | 
					C:
 | 
				
			||||||
  %h = phi double* [ null, %A ], [ %p, %B ]
 | 
					  %h = phi double* [ null, %A ], [ %p, %B ]
 | 
				
			||||||
  %c = bitcast double* %h to i8*
 | 
					  %c = bitcast double* %h to i8*
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue