[Attributor][FIX] NoCapture is not a subsuming property

We cannot look at the subsuming positions and take their nocapture bit
as shown with the two tests for which we derived nocapture on the call
site argument and readonly on the argument of the second before.
This commit is contained in:
Johannes Doerfert 2019-10-31 20:03:13 -05:00
parent 0c7d4d7f3e
commit 0437bfcc83
2 changed files with 43 additions and 5 deletions

View File

@ -3131,7 +3131,16 @@ struct AANoCaptureImpl : public AANoCapture {
/// See AbstractAttribute::initialize(...).
void initialize(Attributor &A) override {
AANoCapture::initialize(A);
if (hasAttr(getAttrKind(), /* IgnoreSubsumingPositions */ true)) {
indicateOptimisticFixpoint();
return;
}
Function *AnchorScope = getAnchorScope();
if (isFnInterfaceKind() &&
(!AnchorScope || !AnchorScope->hasExactDefinition())) {
indicatePessimisticFixpoint();
return;
}
// You cannot "capture" null in the default address space.
if (isa<ConstantPointerNull>(getAssociatedValue()) &&
@ -3140,13 +3149,11 @@ struct AANoCaptureImpl : public AANoCapture {
return;
}
const IRPosition &IRP = getIRPosition();
const Function *F =
getArgNo() >= 0 ? IRP.getAssociatedFunction() : IRP.getAnchorScope();
const Function *F = getArgNo() >= 0 ? getAssociatedFunction() : AnchorScope;
// Check what state the associated function can actually capture.
if (F)
determineFunctionCaptureCapabilities(IRP, *F, *this);
determineFunctionCaptureCapabilities(getIRPosition(), *F, *this);
else
indicatePessimisticFixpoint();
}

View File

@ -437,4 +437,35 @@ entry:
ret i32* %call
}
declare i32* @unknown_i32p(i32*)
define void @nocapture_is_not_subsumed_1(i32* nocapture %b) {
; CHECK-LABEL: define {{[^@]+}}@nocapture_is_not_subsumed_1
; CHECK-SAME: (i32* nocapture [[B:%.*]])
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CALL:%.*]] = call i32* @unknown_i32p(i32* [[B:%.*]])
; CHECK-NEXT: store i32 0, i32* [[CALL]]
; CHECK-NEXT: ret void
;
entry:
%call = call i32* @unknown_i32p(i32* %b)
store i32 0, i32* %call
ret void
}
declare i32* @readonly_i32p(i32*) readonly
define void @nocapture_is_not_subsumed_2(i32* nocapture %b) {
; CHECK-LABEL: define {{[^@]+}}@nocapture_is_not_subsumed_2
; CHECK-SAME: (i32* nocapture [[B:%.*]])
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CALL:%.*]] = call i32* @readonly_i32p(i32* readonly [[B:%.*]])
; CHECK-NEXT: store i32 0, i32* [[CALL]]
; CHECK-NEXT: ret void
;
entry:
%call = call i32* @readonly_i32p(i32* %b)
store i32 0, i32* %call
ret void
}
attributes #0 = { noinline nounwind uwtable }