; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes
-; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=9 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
-; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=9 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
+; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=10 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
+; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=10 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM
; NOT_CGSCC_OPM-NEXT: [[C:%.*]] = icmp eq i32 [[L]], 0
; NOT_CGSCC_OPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
; NOT_CGSCC_OPM: t:
-; NOT_CGSCC_OPM-NEXT: [[R:%.*]] = call i32* @test10a(i32* nofree nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P]]) [[ATTR3]]
-; NOT_CGSCC_OPM-NEXT: store i32 1, i32* [[R]], align 4
+; NOT_CGSCC_OPM-NEXT: [[R:%.*]] = call align 32 i32* @test10a(i32* nofree nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P]]) [[ATTR3]]
+; NOT_CGSCC_OPM-NEXT: store i32 1, i32* [[R]], align 32
; NOT_CGSCC_OPM-NEXT: [[G0:%.*]] = getelementptr i32, i32* [[P]], i32 8
; NOT_CGSCC_OPM-NEXT: br label [[E:%.*]]
; NOT_CGSCC_OPM: f:
; NOT_CGSCC_OPM-NEXT: [[G1:%.*]] = getelementptr i32, i32* [[P]], i32 8
-; NOT_CGSCC_OPM-NEXT: store i32 -1, i32* [[G1]], align 4
+; NOT_CGSCC_OPM-NEXT: store i32 -1, i32* [[G1]], align 32
; NOT_CGSCC_OPM-NEXT: br label [[E]]
; NOT_CGSCC_OPM: e:
; NOT_CGSCC_OPM-NEXT: [[PHI:%.*]] = phi i32* [ [[G0]], [[T]] ], [ [[G1]], [[F]] ]
; IS__CGSCC_OPM-NEXT: [[C:%.*]] = icmp eq i32 [[L]], 0
; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
; IS__CGSCC_OPM: t:
-; IS__CGSCC_OPM-NEXT: [[R:%.*]] = call i32* @test10a(i32* nofree nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P]]) [[ATTR4]]
-; IS__CGSCC_OPM-NEXT: store i32 1, i32* [[R]], align 4
+; IS__CGSCC_OPM-NEXT: [[R:%.*]] = call align 32 i32* @test10a(i32* nofree nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P]]) [[ATTR4]]
+; IS__CGSCC_OPM-NEXT: store i32 1, i32* [[R]], align 32
; IS__CGSCC_OPM-NEXT: [[G0:%.*]] = getelementptr i32, i32* [[P]], i32 8
; IS__CGSCC_OPM-NEXT: br label [[E:%.*]]
; IS__CGSCC_OPM: f:
; IS__CGSCC_OPM-NEXT: [[G1:%.*]] = getelementptr i32, i32* [[P]], i32 8
-; IS__CGSCC_OPM-NEXT: store i32 -1, i32* [[G1]], align 4
+; IS__CGSCC_OPM-NEXT: store i32 -1, i32* [[G1]], align 32
; IS__CGSCC_OPM-NEXT: br label [[E]]
; IS__CGSCC_OPM: e:
; IS__CGSCC_OPM-NEXT: [[PHI:%.*]] = phi i32* [ [[G0]], [[T]] ], [ [[G1]], [[F]] ]
; NOT_CGSCC_OPM-NEXT: [[C:%.*]] = icmp eq i32 [[L]], 0
; NOT_CGSCC_OPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
; NOT_CGSCC_OPM: t:
-; NOT_CGSCC_OPM-NEXT: [[R:%.*]] = call i32* @test10b(i32* nofree nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P]]) [[ATTR3]]
-; NOT_CGSCC_OPM-NEXT: store i32 1, i32* [[R]], align 4
+; NOT_CGSCC_OPM-NEXT: [[R:%.*]] = call align 32 i32* @test10b(i32* nofree nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P]]) [[ATTR3]]
+; NOT_CGSCC_OPM-NEXT: store i32 1, i32* [[R]], align 32
; NOT_CGSCC_OPM-NEXT: [[G0:%.*]] = getelementptr i32, i32* [[P]], i32 8
; NOT_CGSCC_OPM-NEXT: br label [[E:%.*]]
; NOT_CGSCC_OPM: f:
; NOT_CGSCC_OPM-NEXT: [[G1:%.*]] = getelementptr i32, i32* [[P]], i32 -8
-; NOT_CGSCC_OPM-NEXT: store i32 -1, i32* [[G1]], align 4
+; NOT_CGSCC_OPM-NEXT: store i32 -1, i32* [[G1]], align 32
; NOT_CGSCC_OPM-NEXT: br label [[E]]
; NOT_CGSCC_OPM: e:
; NOT_CGSCC_OPM-NEXT: [[PHI:%.*]] = phi i32* [ [[G0]], [[T]] ], [ [[G1]], [[F]] ]
; IS__CGSCC_OPM-NEXT: [[C:%.*]] = icmp eq i32 [[L]], 0
; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
; IS__CGSCC_OPM: t:
-; IS__CGSCC_OPM-NEXT: [[R:%.*]] = call i32* @test10b(i32* nofree nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P]]) [[ATTR4]]
-; IS__CGSCC_OPM-NEXT: store i32 1, i32* [[R]], align 4
+; IS__CGSCC_OPM-NEXT: [[R:%.*]] = call align 32 i32* @test10b(i32* nofree nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P]]) [[ATTR4]]
+; IS__CGSCC_OPM-NEXT: store i32 1, i32* [[R]], align 32
; IS__CGSCC_OPM-NEXT: [[G0:%.*]] = getelementptr i32, i32* [[P]], i32 8
; IS__CGSCC_OPM-NEXT: br label [[E:%.*]]
; IS__CGSCC_OPM: f:
; IS__CGSCC_OPM-NEXT: [[G1:%.*]] = getelementptr i32, i32* [[P]], i32 -8
-; IS__CGSCC_OPM-NEXT: store i32 -1, i32* [[G1]], align 4
+; IS__CGSCC_OPM-NEXT: store i32 -1, i32* [[G1]], align 32
; IS__CGSCC_OPM-NEXT: br label [[E]]
; IS__CGSCC_OPM: e:
; IS__CGSCC_OPM-NEXT: [[PHI:%.*]] = phi i32* [ [[G0]], [[T]] ], [ [[G1]], [[F]] ]
ret i32 0
}
+define i32* @checkAndAdvance(i32* align(16) %p) {
+; NOT_CGSCC_OPM: Function Attrs: nounwind
+; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@checkAndAdvance
+; NOT_CGSCC_OPM-SAME: (i32* nonnull readonly align 16 dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]]) [[ATTR2]] {
+; NOT_CGSCC_OPM-NEXT: entry:
+; NOT_CGSCC_OPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[P]], align 16
+; NOT_CGSCC_OPM-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], 0
+; NOT_CGSCC_OPM-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[RETURN:%.*]]
+; NOT_CGSCC_OPM: if.then:
+; NOT_CGSCC_OPM-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 4
+; NOT_CGSCC_OPM-NEXT: [[CALL:%.*]] = call nonnull align 16 i32* @checkAndAdvance(i32* nonnull readonly align 16 "no-capture-maybe-returned" [[ADD_PTR]]) [[ATTR2]]
+; NOT_CGSCC_OPM-NEXT: br label [[RETURN]]
+; NOT_CGSCC_OPM: return:
+; NOT_CGSCC_OPM-NEXT: [[RETVAL_0:%.*]] = phi i32* [ [[CALL]], [[IF_THEN]] ], [ [[P]], [[ENTRY:%.*]] ]
+; NOT_CGSCC_OPM-NEXT: call void @user_i32_ptr(i32* noalias nocapture nonnull readnone align 16 [[RETVAL_0]]) [[ATTR2]]
+; NOT_CGSCC_OPM-NEXT: ret i32* [[RETVAL_0]]
+;
+; IS__CGSCC_OPM: Function Attrs: nounwind
+; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@checkAndAdvance
+; IS__CGSCC_OPM-SAME: (i32* nonnull readonly align 16 dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]]) [[ATTR3]] {
+; IS__CGSCC_OPM-NEXT: entry:
+; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[P]], align 16
+; IS__CGSCC_OPM-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], 0
+; IS__CGSCC_OPM-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[RETURN:%.*]]
+; IS__CGSCC_OPM: if.then:
+; IS__CGSCC_OPM-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 4
+; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call nonnull align 16 i32* @checkAndAdvance(i32* nonnull readonly align 16 "no-capture-maybe-returned" [[ADD_PTR]]) [[ATTR3]]
+; IS__CGSCC_OPM-NEXT: br label [[RETURN]]
+; IS__CGSCC_OPM: return:
+; IS__CGSCC_OPM-NEXT: [[RETVAL_0:%.*]] = phi i32* [ [[CALL]], [[IF_THEN]] ], [ [[P]], [[ENTRY:%.*]] ]
+; IS__CGSCC_OPM-NEXT: call void @user_i32_ptr(i32* noalias nocapture nonnull readnone align 16 [[RETVAL_0]]) [[ATTR3]]
+; IS__CGSCC_OPM-NEXT: ret i32* [[RETVAL_0]]
+;
+entry:
+ %0 = load i32, i32* %p, align 4
+ %cmp = icmp eq i32 %0, 0
+ br i1 %cmp, label %if.then, label %return
+
+if.then: ; preds = %entry
+ %add.ptr = getelementptr inbounds i32, i32* %p, i64 4
+ %call = call i32* @checkAndAdvance(i32* nonnull %add.ptr)
+ br label %return
+
+return: ; preds = %entry, %if.then
+ %retval.0 = phi i32* [ %call, %if.then ], [ %p, %entry ]
+ call void @user_i32_ptr(i32* %retval.0)
+ ret i32* %retval.0
+}
+
+
attributes #0 = { nounwind uwtable noinline }
attributes #1 = { uwtable noinline }
attributes #2 = { null_pointer_is_valid }