Precommit tests from D104641.
The patch will fix the callsites by dropping the context-sensitive
attributes.
Reviewed-By: Self
ret void
}
+declare i32 @spec(i32* %p) readonly argmemonly nounwind speculatable
+
+; FIXME: We should strip the nonnull callsite attribute on spec call's argument since it is
+; may not be valid when hoisted to preheader.
+define void @test_strip_attribute(i32* noalias %loc, i32* noalias %sink, i32* %q) {
+; CHECK-LABEL: test_strip_attribute
+; CHECK-LABEL: entry
+; CHECK-NEXT: %ret = call i32 @load(i32* %loc)
+; CHECK-NEXT: %nullchk = icmp eq i32* %q, null
+; CHECK-NEXT: %ret2 = call i32 @spec(i32* nonnull %q)
+entry:
+ br label %loop
+
+loop:
+ %iv = phi i32 [0, %entry], [%iv.next, %isnull ]
+ %ret = call i32 @load(i32* %loc)
+ %nullchk = icmp eq i32* %q, null
+ br i1 %nullchk, label %isnull, label %nonnullbb
+
+nonnullbb:
+ %ret2 = call i32 @spec(i32* nonnull %q)
+ br label %isnull
+
+isnull:
+ store volatile i32 %ret, i32* %sink
+ %iv.next = add i32 %iv, 1
+ %cmp = icmp slt i32 %iv, 200
+ br i1 %cmp, label %loop, label %exit
+
+exit:
+ ret void
+}
declare void @store(i32 %val, i32* %p) argmemonly writeonly nounwind
declare void @sideeffect2()
declare void @use8(i8)
declare i1 @gen1()
+declare i32 @speculate_call(i32 *) #0
; Basic cases, blocks have nothing other than the comparison itself.
ret void
}
+; FIXME: When we fold the dispatch block into pred, the call is moved to pred
+; and the attribute nonnull is no longer valid on paramater. We should drop it.
+define void @one_pred_with_spec_call(i8 %v0, i8 %v1, i32* %p) {
+; CHECK-LABEL: one_pred_with_spec_call
+; CHECK-LABEL: pred:
+; CHECK: %c0 = icmp ne i32* %p, null
+; CHECK: %x = call i32 @speculate_call(i32* nonnull %p)
+pred:
+ %c0 = icmp ne i32* %p, null
+ br i1 %c0, label %dispatch, label %final_right
+
+dispatch:
+ %x = call i32 @speculate_call(i32* nonnull %p)
+ %c1 = icmp eq i8 %v1, 0
+ br i1 %c1, label %final_left, label %final_right
+
+final_left:
+ ret void
+
+final_right:
+ call void @sideeffect0()
+ ret void
+}
+
define void @two_preds_with_extra_op(i8 %v0, i8 %v1, i8 %v2, i8 %v3) {
; CHECK-LABEL: @two_preds_with_extra_op(
; CHECK-NEXT: entry:
for.end:
ret void
}
+
+attributes #0 = { nounwind argmemonly speculatable }
define i32 @func() #0 {
ret i32 1
}
+
+; FIXME: We should correctly drop the attribute since it may no longer be valid
+; in the context the call is moved to.
+define i32 @strip_attr(i32 * %p) {
+; CHECK-LABEL: strip_attr
+; CHECK-LABEL: entry:
+; CHECK: %nullchk = icmp ne i32* %p, null
+; CHECK: %val = call i32 @func_deref(i32* nonnull %p)
+; CHECK: select
+entry:
+ %nullchk = icmp ne i32* %p, null
+ br i1 %nullchk, label %if, label %end
+
+if:
+ %val = call i32 @func_deref(i32* nonnull %p) #1
+ br label %end
+
+end:
+ %ret = phi i32 [%val, %if], [0, %entry]
+ ret i32 %ret
+}
+
+declare i32 @func_deref(i32*) #1
+
attributes #0 = { nounwind readnone speculatable }
+attributes #1 = { nounwind argmemonly speculatable }