From 3ca54f45953e4217ad764c68ee2abcbc3eead1e8 Mon Sep 17 00:00:00 2001 From: Johannes Doerfert Date: Wed, 8 Apr 2020 19:04:57 -0500 Subject: [PATCH] [Attributor] Unify testing (=updates,prefixes,run configurations,...) When the Attributor was created the test update scripts were not well suited to deal with the challenges of IR attribute checking. This partially improved. Since then we also added three additional configurations that need testing; in total we now have the following four: { TUNIT, CGSCC } x { old pass manager (OPM), new pass manager (NPM) } Finally, the number of developers and tests grew rapidly (partially due to the addition of ArgumentPromotion and IPConstantProp tests), which resulted in tests only being run in some configurations, different prefixes being used, and different "styles" of checks being used. Due to the above reasons I believed we needed to take another look at the test update scripts. While we started to use them, via UTC_ARGS: --enable/disable, the other problems remained. To improve the testing situation for *all* configurations, to simplify future updates to the test, and to help identify subtle effects of future changes, we now use the test update scripts for (almost) all Attributor tests. An exhaustive prefix list minimizes the number of check lines and makes it easy to identify and compare configurations. Tests have been adjusted in the process but we tried to keep their intend unchanged. Reviewed By: sstefan1 Differential Revision: https://reviews.llvm.org/D76588 --- .../2008-02-01-ReturnAttrs.ll | 63 +- .../2008-07-02-array-indexing.ll | 24 +- .../ArgumentPromotion/2008-09-07-CGUpdate.ll | 14 +- .../2008-09-08-CGUpdateSelfEdge.ll | 22 +- .../ArgumentPromotion/X86/attributes.ll | 165 +- .../X86/min-legal-vector-width.ll | 673 ++++-- .../ArgumentPromotion/X86/thiscall.ll | 70 +- .../ArgumentPromotion/aggregate-promote.ll | 20 +- .../Attributor/ArgumentPromotion/alignment.ll | 55 +- .../Attributor/ArgumentPromotion/attrs.ll | 154 +- .../Attributor/ArgumentPromotion/basictest.ll | 97 +- .../Attributor/ArgumentPromotion/byval-2.ll | 71 +- .../Attributor/ArgumentPromotion/byval.ll | 189 +- .../Attributor/ArgumentPromotion/chained.ll | 6 +- .../ArgumentPromotion/control-flow.ll | 5 +- .../ArgumentPromotion/control-flow2.ll | 67 +- .../Attributor/ArgumentPromotion/crash.ll | 65 +- .../Attributor/ArgumentPromotion/dbg.ll | 21 +- .../Attributor/ArgumentPromotion/fp80.ll | 44 +- .../Attributor/ArgumentPromotion/inalloca.ll | 102 +- .../live_called_from_dead.ll | 64 +- .../live_called_from_dead_2.ll | 137 +- .../Attributor/ArgumentPromotion/musttail.ll | 39 +- .../ArgumentPromotion/naked_functions.ll | 5 +- .../nonzero-address-spaces.ll | 5 +- .../Attributor/ArgumentPromotion/pr27568.ll | 5 +- .../Attributor/ArgumentPromotion/pr3085.ll | 1945 ----------------- .../Attributor/ArgumentPromotion/pr32917.ll | 24 +- .../pr33641_remove_arg_dbgvalue.ll | 5 +- .../Attributor/ArgumentPromotion/profile.ll | 55 +- .../ArgumentPromotion/reserve-tbaa.ll | 51 +- .../Attributor/ArgumentPromotion/sret.ll | 72 +- .../Attributor/ArgumentPromotion/tail.ll | 58 +- .../Attributor/ArgumentPromotion/variadic.ll | 21 +- .../IPConstantProp/2008-06-09-WeakProp.ll | 6 +- .../IPConstantProp/2009-09-24-byval-ptr.ll | 223 +- .../Attributor/IPConstantProp/PR16052.ll | 57 +- .../Attributor/IPConstantProp/PR26044.ll | 104 +- .../Attributor/IPConstantProp/PR43857.ll | 19 +- .../IPConstantProp/arg-count-mismatch.ll | 26 +- .../IPConstantProp/arg-type-mismatch.ll | 5 +- .../Attributor/IPConstantProp/comdat-ipo.ll | 5 +- .../IPConstantProp/dangling-block-address.ll | 40 +- .../Attributor/IPConstantProp/deadarg.ll | 10 +- .../IPConstantProp/fp-bc-icmp-const-fold.ll | 5 +- .../Attributor/IPConstantProp/global.ll | 5 +- .../IPConstantProp/multiple_callbacks.ll | 5 +- .../IPConstantProp/musttail-call.ll | 85 +- .../Attributor/IPConstantProp/naked-return.ll | 5 +- .../IPConstantProp/openmp_parallel_for.ll | 242 +- .../Attributor/IPConstantProp/pthreads.ll | 136 +- .../Attributor/IPConstantProp/recursion.ll | 8 +- .../IPConstantProp/remove-call-inst.ll | 16 +- .../IPConstantProp/return-argument.ll | 98 +- .../IPConstantProp/return-constant.ll | 27 +- .../IPConstantProp/return-constants.ll | 5 +- ...fter-each-resolving-undefs-for-function.ll | 27 +- .../IPConstantProp/thread_local_acs.ll | 18 +- llvm/test/Transforms/Attributor/align.ll | 513 +++-- .../Transforms/Attributor/alwaysinline.ll | 38 +- llvm/test/Transforms/Attributor/callbacks.ll | 387 +++- .../Attributor/dereferenceable-1.ll | 388 +++- .../Attributor/dereferenceable-2.ll | 249 ++- .../Transforms/Attributor/heap_to_stack.ll | 531 ++++- .../Transforms/Attributor/internal-noalias.ll | 152 +- llvm/test/Transforms/Attributor/liveness.ll | 1016 ++++++--- .../Transforms/Attributor/liveness_chains.ll | 8 +- .../Attributor/lvi-after-jumpthreading.ll | 115 +- .../Transforms/Attributor/lvi-for-ashr.ll | 13 +- .../Transforms/Attributor/memory_locations.ll | 66 +- llvm/test/Transforms/Attributor/misc.ll | 121 +- llvm/test/Transforms/Attributor/noalias.ll | 450 +++- .../test/Transforms/Attributor/nocapture-1.ll | 469 +++- .../test/Transforms/Attributor/nocapture-2.ll | 304 ++- llvm/test/Transforms/Attributor/nofree.ll | 267 ++- llvm/test/Transforms/Attributor/nonnull.ll | 756 +++++-- llvm/test/Transforms/Attributor/norecurse.ll | 170 +- llvm/test/Transforms/Attributor/noreturn.ll | 88 +- llvm/test/Transforms/Attributor/nosync.ll | 257 ++- llvm/test/Transforms/Attributor/nounwind.ll | 74 +- llvm/test/Transforms/Attributor/range.ll | 898 +++----- .../read_write_returned_arguments_scc.ll | 169 +- llvm/test/Transforms/Attributor/readattrs.ll | 196 +- llvm/test/Transforms/Attributor/returned.ll | 690 +++++- .../Attributor/undefined_behavior.ll | 239 +- .../Transforms/Attributor/value-simplify.ll | 198 +- llvm/test/Transforms/Attributor/willreturn.ll | 604 +++-- 87 files changed, 9508 insertions(+), 5508 deletions(-) delete mode 100644 llvm/test/Transforms/Attributor/ArgumentPromotion/pr3085.ll diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-02-01-ReturnAttrs.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-02-01-ReturnAttrs.ll index d6a11193a556..f17d077fce73 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-02-01-ReturnAttrs.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-02-01-ReturnAttrs.ll @@ -1,14 +1,29 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes -; RUN: opt -passes=attributor -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=6 -S < %s | FileCheck %s +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=6 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=6 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 define internal i32 @deref(i32* %x) nounwind { -; CHECK-LABEL: define {{[^@]+}}@deref -; CHECK-SAME: (i32 [[TMP0:%.*]]) -; CHECK-NEXT: entry: -; CHECK-NEXT: [[X_PRIV:%.*]] = alloca i32 -; CHECK-NEXT: store i32 [[TMP0]], i32* [[X_PRIV]] -; CHECK-NEXT: [[TMP2:%.*]] = load i32, i32* [[X_PRIV]], align 4 -; CHECK-NEXT: ret i32 [[TMP2]] +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@deref +; IS__TUNIT_OPM-SAME: (i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[X:%.*]]) +; IS__TUNIT_OPM-NEXT: entry: +; IS__TUNIT_OPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[X]], align 4 +; IS__TUNIT_OPM-NEXT: ret i32 [[TMP2]] +; +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@deref +; IS__TUNIT_NPM-SAME: (i32 [[TMP0:%.*]]) +; IS__TUNIT_NPM-NEXT: entry: +; IS__TUNIT_NPM-NEXT: [[X_PRIV:%.*]] = alloca i32 +; IS__TUNIT_NPM-NEXT: store i32 [[TMP0]], i32* [[X_PRIV]] +; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[X_PRIV]], align 4 +; IS__TUNIT_NPM-NEXT: ret i32 [[TMP2]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@deref +; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[X:%.*]]) +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: [[TMP2:%.*]] = load i32, i32* [[X]], align 4 +; IS__CGSCC____-NEXT: ret i32 [[TMP2]] ; entry: %tmp2 = load i32, i32* %x, align 4 @@ -16,14 +31,30 @@ entry: } define i32 @f(i32 %x) { -; CHECK-LABEL: define {{[^@]+}}@f -; CHECK-SAME: (i32 [[X:%.*]]) -; CHECK-NEXT: entry: -; CHECK-NEXT: [[X_ADDR:%.*]] = alloca i32 -; CHECK-NEXT: store i32 [[X]], i32* [[X_ADDR]], align 4 -; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[X_ADDR]], align 1 -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @deref(i32 [[TMP0]]) -; CHECK-NEXT: ret i32 [[TMP1]] +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@f +; IS__TUNIT_OPM-SAME: (i32 [[X:%.*]]) +; IS__TUNIT_OPM-NEXT: entry: +; IS__TUNIT_OPM-NEXT: [[X_ADDR:%.*]] = alloca i32 +; IS__TUNIT_OPM-NEXT: store i32 [[X]], i32* [[X_ADDR]], align 4 +; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = call i32 @deref(i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[X_ADDR]]) +; IS__TUNIT_OPM-NEXT: ret i32 [[TMP1]] +; +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@f +; IS__TUNIT_NPM-SAME: (i32 [[X:%.*]]) +; IS__TUNIT_NPM-NEXT: entry: +; IS__TUNIT_NPM-NEXT: [[X_ADDR:%.*]] = alloca i32 +; IS__TUNIT_NPM-NEXT: store i32 [[X]], i32* [[X_ADDR]], align 4 +; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[X_ADDR]], align 1 +; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = call i32 @deref(i32 [[TMP0]]) +; IS__TUNIT_NPM-NEXT: ret i32 [[TMP1]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@f +; IS__CGSCC____-SAME: (i32 [[X:%.*]]) +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: [[X_ADDR:%.*]] = alloca i32 +; IS__CGSCC____-NEXT: store i32 [[X]], i32* [[X_ADDR]], align 4 +; IS__CGSCC____-NEXT: [[TMP1:%.*]] = call i32 @deref(i32* noalias nofree nonnull readonly align 4 dereferenceable(4) [[X_ADDR]]) +; IS__CGSCC____-NEXT: ret i32 [[TMP1]] ; entry: %x_addr = alloca i32 diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-07-02-array-indexing.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-07-02-array-indexing.ll index 9a4956be40a5..92eaeb0f3edc 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-07-02-array-indexing.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-07-02-array-indexing.ll @@ -1,20 +1,24 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes -; RUN: opt -passes=attributor -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=3 -S < %s | FileCheck %s +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 ; PR2498 ; This test tries to convince CHECK about promoting the load from %A + 2, ; because there is a load of %A in the entry block define internal i32 @callee(i1 %C, i32* %A) { +; ; CHECK-LABEL: define {{[^@]+}}@callee ; CHECK-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) ; CHECK-NEXT: entry: -; CHECK-NEXT: [[A_0:%.*]] = load i32, i32* %A +; CHECK-NEXT: [[A_0:%.*]] = load i32, i32* [[A]], align 4 ; CHECK-NEXT: br label [[F:%.*]] ; CHECK: T: ; CHECK-NEXT: unreachable ; CHECK: F: -; CHECK-NEXT: [[A_2:%.*]] = getelementptr i32, i32* %A, i32 2 -; CHECK-NEXT: [[R:%.*]] = load i32, i32* [[A_2]] +; CHECK-NEXT: [[A_2:%.*]] = getelementptr i32, i32* [[A]], i32 2 +; CHECK-NEXT: [[R:%.*]] = load i32, i32* [[A_2]], align 4 ; CHECK-NEXT: ret i32 [[R]] ; entry: @@ -33,9 +37,15 @@ F: } define i32 @foo(i32* %A) { -; CHECK-LABEL: define {{[^@]+}}@foo( -; CHECK-NEXT: [[X:%.*]] = call i32 @callee(i32* nocapture nofree readonly align 4 %A) -; CHECK-NEXT: ret i32 [[X]] +; IS__TUNIT____-LABEL: define {{[^@]+}}@foo +; IS__TUNIT____-SAME: (i32* nocapture nofree readonly [[A:%.*]]) +; IS__TUNIT____-NEXT: [[X:%.*]] = call i32 @callee(i32* nocapture nofree readonly align 4 [[A]]) +; IS__TUNIT____-NEXT: ret i32 [[X]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@foo +; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) +; IS__CGSCC____-NEXT: [[X:%.*]] = call i32 @callee(i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A]]) +; IS__CGSCC____-NEXT: ret i32 [[X]] ; %X = call i32 @callee(i1 false, i32* %A) ; [#uses=1] ret i32 %X diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-09-07-CGUpdate.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-09-07-CGUpdate.ll index fd2887ecea60..2854f7111867 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-09-07-CGUpdate.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-09-07-CGUpdate.ll @@ -1,12 +1,24 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes -; RUN: opt -disable-output -passes=attributor -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=1 < %s +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 define internal fastcc i32 @hash(i32* %ts, i32 %mod) nounwind { +; IS__CGSCC____-LABEL: define {{[^@]+}}@hash() +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: unreachable +; entry: unreachable } define void @encode(i32* %m, i32* %ts, i32* %new) nounwind { +; CHECK-LABEL: define {{[^@]+}}@encode +; CHECK-SAME: (i32* nocapture nofree readnone [[M:%.*]], i32* nocapture nofree readnone [[TS:%.*]], i32* nocapture nofree readnone [[NEW:%.*]]) +; CHECK-NEXT: entry: +; CHECK-NEXT: unreachable +; entry: %0 = call fastcc i32 @hash( i32* %ts, i32 0 ) nounwind ; [#uses=0] unreachable diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-09-08-CGUpdateSelfEdge.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-09-08-CGUpdateSelfEdge.ll index fe3f1c697436..c179dd52bbe5 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-09-08-CGUpdateSelfEdge.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-09-08-CGUpdateSelfEdge.ll @@ -1,7 +1,18 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes -; RUN: opt -disable-output -passes=attributor -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=1 < %s +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 define internal fastcc i32 @term_SharingList(i32* %Term, i32* %List) nounwind { +; IS__CGSCC____-LABEL: define {{[^@]+}}@term_SharingList() +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: br i1 false, label [[BB:%.*]], label [[BB5:%.*]] +; IS__CGSCC____: bb: +; IS__CGSCC____-NEXT: unreachable +; IS__CGSCC____: bb5: +; IS__CGSCC____-NEXT: ret i32 undef +; entry: br i1 false, label %bb, label %bb5 @@ -14,6 +25,15 @@ bb5: ; preds = %entry } define i32 @term_Sharing(i32* %Term) nounwind { +; CHECK-LABEL: define {{[^@]+}}@term_Sharing +; CHECK-SAME: (i32* nocapture nofree readnone [[TERM:%.*]]) +; CHECK-NEXT: entry: +; CHECK-NEXT: br i1 false, label [[BB_I:%.*]], label [[BB14:%.*]] +; CHECK: bb.i: +; CHECK-NEXT: unreachable +; CHECK: bb14: +; CHECK-NEXT: ret i32 0 +; entry: br i1 false, label %bb.i, label %bb14 diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/attributes.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/attributes.ll index 08e254f382ec..dc99e85c12fd 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/attributes.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/attributes.ll @@ -1,17 +1,27 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes -; RUN: opt -S -passes='attributor' -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=3 < %s | FileCheck %s +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 ; Test that we only promote arguments when the caller/callee have compatible ; function attrubtes. target triple = "x86_64-unknown-linux-gnu" define internal fastcc void @no_promote_avx2(<4 x i64>* %arg, <4 x i64>* readonly %arg1) #0 { -; CHECK-LABEL: define {{[^@]+}}@no_promote_avx2 -; CHECK-SAME: (<4 x i64>* noalias nocapture nofree nonnull writeonly align 32 dereferenceable(32) [[ARG:%.*]], <4 x i64>* noalias nocapture nofree nonnull readonly align 32 dereferenceable(32) [[ARG1:%.*]]) -; CHECK-NEXT: bb: -; CHECK-NEXT: [[TMP:%.*]] = load <4 x i64>, <4 x i64>* [[ARG1]], align 32 -; CHECK-NEXT: store <4 x i64> [[TMP]], <4 x i64>* [[ARG]], align 32 -; CHECK-NEXT: ret void +; NOT_TUNIT_NPM-LABEL: define {{[^@]+}}@no_promote_avx2 +; NOT_TUNIT_NPM-SAME: (<4 x i64>* nocapture nofree nonnull writeonly align 32 dereferenceable(32) [[ARG:%.*]], <4 x i64>* nocapture nofree nonnull readonly align 32 dereferenceable(32) [[ARG1:%.*]]) +; NOT_TUNIT_NPM-NEXT: bb: +; NOT_TUNIT_NPM-NEXT: [[TMP:%.*]] = load <4 x i64>, <4 x i64>* [[ARG1]], align 32 +; NOT_TUNIT_NPM-NEXT: store <4 x i64> [[TMP]], <4 x i64>* [[ARG]], align 32 +; NOT_TUNIT_NPM-NEXT: ret void +; +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@no_promote_avx2 +; IS__TUNIT_NPM-SAME: (<4 x i64>* noalias nocapture nofree nonnull writeonly align 32 dereferenceable(32) [[ARG:%.*]], <4 x i64>* noalias nocapture nofree nonnull readonly align 32 dereferenceable(32) [[ARG1:%.*]]) +; IS__TUNIT_NPM-NEXT: bb: +; IS__TUNIT_NPM-NEXT: [[TMP:%.*]] = load <4 x i64>, <4 x i64>* [[ARG1]], align 32 +; IS__TUNIT_NPM-NEXT: store <4 x i64> [[TMP]], <4 x i64>* [[ARG]], align 32 +; IS__TUNIT_NPM-NEXT: ret void ; bb: %tmp = load <4 x i64>, <4 x i64>* %arg1 @@ -20,17 +30,53 @@ bb: } define void @no_promote(<4 x i64>* %arg) #1 { -; CHECK-LABEL: define {{[^@]+}}@no_promote -; CHECK-SAME: (<4 x i64>* nocapture writeonly [[ARG:%.*]]) -; CHECK-NEXT: bb: -; CHECK-NEXT: [[TMP:%.*]] = alloca <4 x i64>, align 32 -; CHECK-NEXT: [[TMP2:%.*]] = alloca <4 x i64>, align 32 -; CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i64>* [[TMP]] to i8* -; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull writeonly align 32 dereferenceable(32) [[TMP3]], i8 0, i64 32, i1 false) -; CHECK-NEXT: call fastcc void @no_promote_avx2(<4 x i64>* noalias nocapture nofree nonnull writeonly align 32 dereferenceable(32) [[TMP2]], <4 x i64>* noalias nocapture nofree nonnull readonly align 32 dereferenceable(32) [[TMP]]) -; CHECK-NEXT: [[TMP4:%.*]] = load <4 x i64>, <4 x i64>* [[TMP2]], align 32 -; CHECK-NEXT: store <4 x i64> [[TMP4]], <4 x i64>* [[ARG]], align 2 -; CHECK-NEXT: ret void +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@no_promote +; IS__TUNIT_OPM-SAME: (<4 x i64>* nocapture writeonly [[ARG:%.*]]) +; IS__TUNIT_OPM-NEXT: bb: +; IS__TUNIT_OPM-NEXT: [[TMP:%.*]] = alloca <4 x i64>, align 32 +; IS__TUNIT_OPM-NEXT: [[TMP2:%.*]] = alloca <4 x i64>, align 32 +; IS__TUNIT_OPM-NEXT: [[TMP3:%.*]] = bitcast <4 x i64>* [[TMP]] to i8* +; IS__TUNIT_OPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull writeonly align 32 dereferenceable(32) [[TMP3]], i8 0, i64 32, i1 false) +; IS__TUNIT_OPM-NEXT: call fastcc void @no_promote_avx2(<4 x i64>* nocapture nofree nonnull writeonly align 32 dereferenceable(32) [[TMP2]], <4 x i64>* nocapture nofree nonnull readonly align 32 dereferenceable(32) [[TMP]]) +; IS__TUNIT_OPM-NEXT: [[TMP4:%.*]] = load <4 x i64>, <4 x i64>* [[TMP2]], align 32 +; IS__TUNIT_OPM-NEXT: store <4 x i64> [[TMP4]], <4 x i64>* [[ARG]], align 2 +; IS__TUNIT_OPM-NEXT: ret void +; +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@no_promote +; IS__TUNIT_NPM-SAME: (<4 x i64>* nocapture writeonly [[ARG:%.*]]) +; IS__TUNIT_NPM-NEXT: bb: +; IS__TUNIT_NPM-NEXT: [[TMP:%.*]] = alloca <4 x i64>, align 32 +; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = alloca <4 x i64>, align 32 +; IS__TUNIT_NPM-NEXT: [[TMP3:%.*]] = bitcast <4 x i64>* [[TMP]] to i8* +; IS__TUNIT_NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull writeonly align 32 dereferenceable(32) [[TMP3]], i8 0, i64 32, i1 false) +; IS__TUNIT_NPM-NEXT: call fastcc void @no_promote_avx2(<4 x i64>* noalias nocapture nofree nonnull writeonly align 32 dereferenceable(32) [[TMP2]], <4 x i64>* noalias nocapture nofree nonnull readonly align 32 dereferenceable(32) [[TMP]]) +; IS__TUNIT_NPM-NEXT: [[TMP4:%.*]] = load <4 x i64>, <4 x i64>* [[TMP2]], align 32 +; IS__TUNIT_NPM-NEXT: store <4 x i64> [[TMP4]], <4 x i64>* [[ARG]], align 2 +; IS__TUNIT_NPM-NEXT: ret void +; +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@no_promote +; IS__CGSCC_OPM-SAME: (<4 x i64>* nocapture nonnull writeonly align 2 dereferenceable(32) [[ARG:%.*]]) +; IS__CGSCC_OPM-NEXT: bb: +; IS__CGSCC_OPM-NEXT: [[TMP:%.*]] = alloca <4 x i64>, align 32 +; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = alloca <4 x i64>, align 32 +; IS__CGSCC_OPM-NEXT: [[TMP3:%.*]] = bitcast <4 x i64>* [[TMP]] to i8* +; IS__CGSCC_OPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull writeonly align 32 dereferenceable(32) [[TMP3]], i8 0, i64 32, i1 false) +; IS__CGSCC_OPM-NEXT: call fastcc void @no_promote_avx2(<4 x i64>* nofree nonnull writeonly align 32 dereferenceable(32) [[TMP2]], <4 x i64>* nofree nonnull readonly align 32 dereferenceable(32) [[TMP]]) +; IS__CGSCC_OPM-NEXT: [[TMP4:%.*]] = load <4 x i64>, <4 x i64>* [[TMP2]], align 32 +; IS__CGSCC_OPM-NEXT: store <4 x i64> [[TMP4]], <4 x i64>* [[ARG]], align 2 +; IS__CGSCC_OPM-NEXT: ret void +; +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@no_promote +; IS__CGSCC_NPM-SAME: (<4 x i64>* nocapture nonnull writeonly align 2 dereferenceable(32) [[ARG:%.*]]) +; IS__CGSCC_NPM-NEXT: bb: +; IS__CGSCC_NPM-NEXT: [[TMP:%.*]] = alloca <4 x i64>, align 32 +; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = alloca <4 x i64>, align 32 +; IS__CGSCC_NPM-NEXT: [[TMP3:%.*]] = bitcast <4 x i64>* [[TMP]] to i8* +; IS__CGSCC_NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull writeonly align 32 dereferenceable(32) [[TMP3]], i8 0, i64 32, i1 false) +; IS__CGSCC_NPM-NEXT: call fastcc void @no_promote_avx2(<4 x i64>* noalias nofree nonnull writeonly align 32 dereferenceable(32) [[TMP2]], <4 x i64>* noalias nofree nonnull readonly align 32 dereferenceable(32) [[TMP]]) +; IS__CGSCC_NPM-NEXT: [[TMP4:%.*]] = load <4 x i64>, <4 x i64>* [[TMP2]], align 32 +; IS__CGSCC_NPM-NEXT: store <4 x i64> [[TMP4]], <4 x i64>* [[ARG]], align 2 +; IS__CGSCC_NPM-NEXT: ret void ; bb: %tmp = alloca <4 x i64>, align 32 @@ -44,14 +90,21 @@ bb: } define internal fastcc void @promote_avx2(<4 x i64>* %arg, <4 x i64>* readonly %arg1) #0 { -; CHECK-LABEL: define {{[^@]+}}@promote_avx2 -; CHECK-SAME: (<4 x i64>* noalias nocapture nofree nonnull writeonly align 32 dereferenceable(32) [[ARG:%.*]], <4 x i64> [[TMP0:%.*]]) -; CHECK-NEXT: bb: -; CHECK-NEXT: [[ARG1_PRIV:%.*]] = alloca <4 x i64> -; CHECK-NEXT: store <4 x i64> [[TMP0]], <4 x i64>* [[ARG1_PRIV]] -; CHECK-NEXT: [[TMP:%.*]] = load <4 x i64>, <4 x i64>* [[ARG1_PRIV]], align 32 -; CHECK-NEXT: store <4 x i64> [[TMP]], <4 x i64>* [[ARG]], align 32 -; CHECK-NEXT: ret void +; NOT_TUNIT_NPM-LABEL: define {{[^@]+}}@promote_avx2 +; NOT_TUNIT_NPM-SAME: (<4 x i64>* nocapture nofree nonnull writeonly align 32 dereferenceable(32) [[ARG:%.*]], <4 x i64>* nocapture nofree nonnull readonly align 32 dereferenceable(32) [[ARG1:%.*]]) +; NOT_TUNIT_NPM-NEXT: bb: +; NOT_TUNIT_NPM-NEXT: [[TMP:%.*]] = load <4 x i64>, <4 x i64>* [[ARG1]], align 32 +; NOT_TUNIT_NPM-NEXT: store <4 x i64> [[TMP]], <4 x i64>* [[ARG]], align 32 +; NOT_TUNIT_NPM-NEXT: ret void +; +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@promote_avx2 +; IS__TUNIT_NPM-SAME: (<4 x i64>* noalias nocapture nofree nonnull writeonly align 32 dereferenceable(32) [[ARG:%.*]], <4 x i64> [[TMP0:%.*]]) +; IS__TUNIT_NPM-NEXT: bb: +; IS__TUNIT_NPM-NEXT: [[ARG1_PRIV:%.*]] = alloca <4 x i64> +; IS__TUNIT_NPM-NEXT: store <4 x i64> [[TMP0]], <4 x i64>* [[ARG1_PRIV]] +; IS__TUNIT_NPM-NEXT: [[TMP:%.*]] = load <4 x i64>, <4 x i64>* [[ARG1_PRIV]], align 32 +; IS__TUNIT_NPM-NEXT: store <4 x i64> [[TMP]], <4 x i64>* [[ARG]], align 32 +; IS__TUNIT_NPM-NEXT: ret void ; bb: %tmp = load <4 x i64>, <4 x i64>* %arg1 @@ -60,18 +113,54 @@ bb: } define void @promote(<4 x i64>* %arg) #0 { -; CHECK-LABEL: define {{[^@]+}}@promote -; CHECK-SAME: (<4 x i64>* nocapture writeonly [[ARG:%.*]]) -; CHECK-NEXT: bb: -; CHECK-NEXT: [[TMP:%.*]] = alloca <4 x i64>, align 32 -; CHECK-NEXT: [[TMP2:%.*]] = alloca <4 x i64>, align 32 -; CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i64>* [[TMP]] to i8* -; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull writeonly align 32 dereferenceable(32) [[TMP3]], i8 0, i64 32, i1 false) -; CHECK-NEXT: [[TMP0:%.*]] = load <4 x i64>, <4 x i64>* [[TMP]], align 1 -; CHECK-NEXT: call fastcc void @promote_avx2(<4 x i64>* noalias nocapture nofree nonnull writeonly align 32 dereferenceable(32) [[TMP2]], <4 x i64> [[TMP0]]) -; CHECK-NEXT: [[TMP4:%.*]] = load <4 x i64>, <4 x i64>* [[TMP2]], align 32 -; CHECK-NEXT: store <4 x i64> [[TMP4]], <4 x i64>* [[ARG]], align 2 -; CHECK-NEXT: ret void +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@promote +; IS__TUNIT_OPM-SAME: (<4 x i64>* nocapture writeonly [[ARG:%.*]]) +; IS__TUNIT_OPM-NEXT: bb: +; IS__TUNIT_OPM-NEXT: [[TMP:%.*]] = alloca <4 x i64>, align 32 +; IS__TUNIT_OPM-NEXT: [[TMP2:%.*]] = alloca <4 x i64>, align 32 +; IS__TUNIT_OPM-NEXT: [[TMP3:%.*]] = bitcast <4 x i64>* [[TMP]] to i8* +; IS__TUNIT_OPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull writeonly align 32 dereferenceable(32) [[TMP3]], i8 0, i64 32, i1 false) +; IS__TUNIT_OPM-NEXT: call fastcc void @promote_avx2(<4 x i64>* nocapture nofree nonnull writeonly align 32 dereferenceable(32) [[TMP2]], <4 x i64>* nocapture nofree nonnull readonly align 32 dereferenceable(32) [[TMP]]) +; IS__TUNIT_OPM-NEXT: [[TMP4:%.*]] = load <4 x i64>, <4 x i64>* [[TMP2]], align 32 +; IS__TUNIT_OPM-NEXT: store <4 x i64> [[TMP4]], <4 x i64>* [[ARG]], align 2 +; IS__TUNIT_OPM-NEXT: ret void +; +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@promote +; IS__TUNIT_NPM-SAME: (<4 x i64>* nocapture writeonly [[ARG:%.*]]) +; IS__TUNIT_NPM-NEXT: bb: +; IS__TUNIT_NPM-NEXT: [[TMP:%.*]] = alloca <4 x i64>, align 32 +; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = alloca <4 x i64>, align 32 +; IS__TUNIT_NPM-NEXT: [[TMP3:%.*]] = bitcast <4 x i64>* [[TMP]] to i8* +; IS__TUNIT_NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull writeonly align 32 dereferenceable(32) [[TMP3]], i8 0, i64 32, i1 false) +; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load <4 x i64>, <4 x i64>* [[TMP]], align 1 +; IS__TUNIT_NPM-NEXT: call fastcc void @promote_avx2(<4 x i64>* noalias nocapture nofree nonnull writeonly align 32 dereferenceable(32) [[TMP2]], <4 x i64> [[TMP0]]) +; IS__TUNIT_NPM-NEXT: [[TMP4:%.*]] = load <4 x i64>, <4 x i64>* [[TMP2]], align 32 +; IS__TUNIT_NPM-NEXT: store <4 x i64> [[TMP4]], <4 x i64>* [[ARG]], align 2 +; IS__TUNIT_NPM-NEXT: ret void +; +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@promote +; IS__CGSCC_OPM-SAME: (<4 x i64>* nocapture nonnull writeonly align 2 dereferenceable(32) [[ARG:%.*]]) +; IS__CGSCC_OPM-NEXT: bb: +; IS__CGSCC_OPM-NEXT: [[TMP:%.*]] = alloca <4 x i64>, align 32 +; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = alloca <4 x i64>, align 32 +; IS__CGSCC_OPM-NEXT: [[TMP3:%.*]] = bitcast <4 x i64>* [[TMP]] to i8* +; IS__CGSCC_OPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull writeonly align 32 dereferenceable(32) [[TMP3]], i8 0, i64 32, i1 false) +; IS__CGSCC_OPM-NEXT: call fastcc void @promote_avx2(<4 x i64>* nofree nonnull writeonly align 32 dereferenceable(32) [[TMP2]], <4 x i64>* nofree nonnull readonly align 32 dereferenceable(32) [[TMP]]) +; IS__CGSCC_OPM-NEXT: [[TMP4:%.*]] = load <4 x i64>, <4 x i64>* [[TMP2]], align 32 +; IS__CGSCC_OPM-NEXT: store <4 x i64> [[TMP4]], <4 x i64>* [[ARG]], align 2 +; IS__CGSCC_OPM-NEXT: ret void +; +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@promote +; IS__CGSCC_NPM-SAME: (<4 x i64>* nocapture nonnull writeonly align 2 dereferenceable(32) [[ARG:%.*]]) +; IS__CGSCC_NPM-NEXT: bb: +; IS__CGSCC_NPM-NEXT: [[TMP:%.*]] = alloca <4 x i64>, align 32 +; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = alloca <4 x i64>, align 32 +; IS__CGSCC_NPM-NEXT: [[TMP3:%.*]] = bitcast <4 x i64>* [[TMP]] to i8* +; IS__CGSCC_NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull writeonly align 32 dereferenceable(32) [[TMP3]], i8 0, i64 32, i1 false) +; IS__CGSCC_NPM-NEXT: call fastcc void @promote_avx2(<4 x i64>* noalias nofree nonnull writeonly align 32 dereferenceable(32) [[TMP2]], <4 x i64>* noalias nofree nonnull readonly align 32 dereferenceable(32) [[TMP]]) +; IS__CGSCC_NPM-NEXT: [[TMP4:%.*]] = load <4 x i64>, <4 x i64>* [[TMP2]], align 32 +; IS__CGSCC_NPM-NEXT: store <4 x i64> [[TMP4]], <4 x i64>* [[ARG]], align 2 +; IS__CGSCC_NPM-NEXT: ret void ; bb: %tmp = alloca <4 x i64>, align 32 diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/min-legal-vector-width.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/min-legal-vector-width.ll index b994aba78dc8..ead9a0e10f71 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/min-legal-vector-width.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/min-legal-vector-width.ll @@ -1,5 +1,8 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes -; RUN: opt -S -passes='attributor' -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=3 < %s | FileCheck %s +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 ; Test that we only promote arguments when the caller/callee have compatible ; function attrubtes. @@ -7,14 +10,22 @@ target triple = "x86_64-unknown-linux-gnu" ; This should promote define internal fastcc void @callee_avx512_legal512_prefer512_call_avx512_legal512_prefer512(<8 x i64>* %arg, <8 x i64>* readonly %arg1) #0 { -; CHECK-LABEL: define {{[^@]+}}@callee_avx512_legal512_prefer512_call_avx512_legal512_prefer512 -; CHECK-SAME: (<8 x i64>* noalias nocapture nofree nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64> [[TMP0:%.*]]) -; CHECK-NEXT: bb: -; CHECK-NEXT: [[ARG1_PRIV:%.*]] = alloca <8 x i64> -; CHECK-NEXT: store <8 x i64> [[TMP0]], <8 x i64>* [[ARG1_PRIV]] -; CHECK-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1_PRIV]], align 64 -; CHECK-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64 -; CHECK-NEXT: ret void +; +; NOT_TUNIT_NPM-LABEL: define {{[^@]+}}@callee_avx512_legal512_prefer512_call_avx512_legal512_prefer512 +; NOT_TUNIT_NPM-SAME: (<8 x i64>* nocapture nofree nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64>* nocapture nofree nonnull readonly align 64 dereferenceable(64) [[ARG1:%.*]]) +; NOT_TUNIT_NPM-NEXT: bb: +; NOT_TUNIT_NPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1]], align 64 +; NOT_TUNIT_NPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64 +; NOT_TUNIT_NPM-NEXT: ret void +; +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@callee_avx512_legal512_prefer512_call_avx512_legal512_prefer512 +; IS__TUNIT_NPM-SAME: (<8 x i64>* noalias nocapture nofree nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64> [[TMP0:%.*]]) +; IS__TUNIT_NPM-NEXT: bb: +; IS__TUNIT_NPM-NEXT: [[ARG1_PRIV:%.*]] = alloca <8 x i64> +; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP0]], <8 x i64>* [[ARG1_PRIV]] +; IS__TUNIT_NPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1_PRIV]], align 64 +; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64 +; IS__TUNIT_NPM-NEXT: ret void ; bb: %tmp = load <8 x i64>, <8 x i64>* %arg1 @@ -23,18 +34,55 @@ bb: } define void @avx512_legal512_prefer512_call_avx512_legal512_prefer512(<8 x i64>* %arg) #0 { -; CHECK-LABEL: define {{[^@]+}}@avx512_legal512_prefer512_call_avx512_legal512_prefer512 -; CHECK-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]]) -; CHECK-NEXT: bb: -; CHECK-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32 -; CHECK-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32 -; CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8* -; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull writeonly align 32 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false) -; CHECK-NEXT: [[TMP0:%.*]] = load <8 x i64>, <8 x i64>* [[TMP]], align 1 -; CHECK-NEXT: call fastcc void @callee_avx512_legal512_prefer512_call_avx512_legal512_prefer512(<8 x i64>* noalias nocapture nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64> [[TMP0]]) -; CHECK-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]], align 64 -; CHECK-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 -; CHECK-NEXT: ret void +; +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@avx512_legal512_prefer512_call_avx512_legal512_prefer512 +; IS__TUNIT_OPM-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]]) +; IS__TUNIT_OPM-NEXT: bb: +; IS__TUNIT_OPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32 +; IS__TUNIT_OPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32 +; IS__TUNIT_OPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8* +; IS__TUNIT_OPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false) +; IS__TUNIT_OPM-NEXT: call fastcc void @callee_avx512_legal512_prefer512_call_avx512_legal512_prefer512(<8 x i64>* nocapture nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64>* nocapture nofree nonnull readonly align 64 dereferenceable(64) [[TMP]]) +; IS__TUNIT_OPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]], align 64 +; IS__TUNIT_OPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 +; IS__TUNIT_OPM-NEXT: ret void +; +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@avx512_legal512_prefer512_call_avx512_legal512_prefer512 +; IS__TUNIT_NPM-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]]) +; IS__TUNIT_NPM-NEXT: bb: +; IS__TUNIT_NPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32 +; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32 +; IS__TUNIT_NPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8* +; IS__TUNIT_NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false) +; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load <8 x i64>, <8 x i64>* [[TMP]], align 1 +; IS__TUNIT_NPM-NEXT: call fastcc void @callee_avx512_legal512_prefer512_call_avx512_legal512_prefer512(<8 x i64>* noalias nocapture nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64> [[TMP0]]) +; IS__TUNIT_NPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]], align 64 +; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 +; IS__TUNIT_NPM-NEXT: ret void +; +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@avx512_legal512_prefer512_call_avx512_legal512_prefer512 +; IS__CGSCC_OPM-SAME: (<8 x i64>* nocapture nonnull writeonly align 2 dereferenceable(64) [[ARG:%.*]]) +; IS__CGSCC_OPM-NEXT: bb: +; IS__CGSCC_OPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32 +; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32 +; IS__CGSCC_OPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8* +; IS__CGSCC_OPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false) +; IS__CGSCC_OPM-NEXT: call fastcc void @callee_avx512_legal512_prefer512_call_avx512_legal512_prefer512(<8 x i64>* nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64>* nofree nonnull readonly align 64 dereferenceable(64) [[TMP]]) +; IS__CGSCC_OPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]], align 64 +; IS__CGSCC_OPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 +; IS__CGSCC_OPM-NEXT: ret void +; +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@avx512_legal512_prefer512_call_avx512_legal512_prefer512 +; IS__CGSCC_NPM-SAME: (<8 x i64>* nocapture nonnull writeonly align 2 dereferenceable(64) [[ARG:%.*]]) +; IS__CGSCC_NPM-NEXT: bb: +; IS__CGSCC_NPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32 +; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32 +; IS__CGSCC_NPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8* +; IS__CGSCC_NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false) +; IS__CGSCC_NPM-NEXT: call fastcc void @callee_avx512_legal512_prefer512_call_avx512_legal512_prefer512(<8 x i64>* noalias nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64>* noalias nofree nonnull readonly align 64 dereferenceable(64) [[TMP]]) +; IS__CGSCC_NPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]], align 64 +; IS__CGSCC_NPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 +; IS__CGSCC_NPM-NEXT: ret void ; bb: %tmp = alloca <8 x i64>, align 32 @@ -49,14 +97,22 @@ bb: ; This should promote define internal fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal512_prefer256(<8 x i64>* %arg, <8 x i64>* readonly %arg1) #1 { -; CHECK-LABEL: define {{[^@]+}}@callee_avx512_legal512_prefer256_call_avx512_legal512_prefer256 -; CHECK-SAME: (<8 x i64>* noalias nocapture nofree nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64> [[TMP0:%.*]]) -; CHECK-NEXT: bb: -; CHECK-NEXT: [[ARG1_PRIV:%.*]] = alloca <8 x i64> -; CHECK-NEXT: store <8 x i64> [[TMP0]], <8 x i64>* [[ARG1_PRIV]] -; CHECK-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1_PRIV]], align 64 -; CHECK-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64 -; CHECK-NEXT: ret void +; +; NOT_TUNIT_NPM-LABEL: define {{[^@]+}}@callee_avx512_legal512_prefer256_call_avx512_legal512_prefer256 +; NOT_TUNIT_NPM-SAME: (<8 x i64>* nocapture nofree nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64>* nocapture nofree nonnull readonly align 64 dereferenceable(64) [[ARG1:%.*]]) +; NOT_TUNIT_NPM-NEXT: bb: +; NOT_TUNIT_NPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1]], align 64 +; NOT_TUNIT_NPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64 +; NOT_TUNIT_NPM-NEXT: ret void +; +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@callee_avx512_legal512_prefer256_call_avx512_legal512_prefer256 +; IS__TUNIT_NPM-SAME: (<8 x i64>* noalias nocapture nofree nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64> [[TMP0:%.*]]) +; IS__TUNIT_NPM-NEXT: bb: +; IS__TUNIT_NPM-NEXT: [[ARG1_PRIV:%.*]] = alloca <8 x i64> +; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP0]], <8 x i64>* [[ARG1_PRIV]] +; IS__TUNIT_NPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1_PRIV]], align 64 +; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64 +; IS__TUNIT_NPM-NEXT: ret void ; bb: %tmp = load <8 x i64>, <8 x i64>* %arg1 @@ -65,18 +121,55 @@ bb: } define void @avx512_legal512_prefer256_call_avx512_legal512_prefer256(<8 x i64>* %arg) #1 { -; CHECK-LABEL: define {{[^@]+}}@avx512_legal512_prefer256_call_avx512_legal512_prefer256 -; CHECK-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]]) -; CHECK-NEXT: bb: -; CHECK-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32 -; CHECK-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32 -; CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8* -; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull writeonly align 32 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false) -; CHECK-NEXT: [[TMP0:%.*]] = load <8 x i64>, <8 x i64>* [[TMP]], align 1 -; CHECK-NEXT: call fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal512_prefer256(<8 x i64>* noalias nocapture nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64> [[TMP0]]) -; CHECK-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]], align 64 -; CHECK-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 -; CHECK-NEXT: ret void +; +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@avx512_legal512_prefer256_call_avx512_legal512_prefer256 +; IS__TUNIT_OPM-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]]) +; IS__TUNIT_OPM-NEXT: bb: +; IS__TUNIT_OPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32 +; IS__TUNIT_OPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32 +; IS__TUNIT_OPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8* +; IS__TUNIT_OPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false) +; IS__TUNIT_OPM-NEXT: call fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal512_prefer256(<8 x i64>* nocapture nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64>* nocapture nofree nonnull readonly align 64 dereferenceable(64) [[TMP]]) +; IS__TUNIT_OPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]], align 64 +; IS__TUNIT_OPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 +; IS__TUNIT_OPM-NEXT: ret void +; +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@avx512_legal512_prefer256_call_avx512_legal512_prefer256 +; IS__TUNIT_NPM-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]]) +; IS__TUNIT_NPM-NEXT: bb: +; IS__TUNIT_NPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32 +; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32 +; IS__TUNIT_NPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8* +; IS__TUNIT_NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false) +; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load <8 x i64>, <8 x i64>* [[TMP]], align 1 +; IS__TUNIT_NPM-NEXT: call fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal512_prefer256(<8 x i64>* noalias nocapture nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64> [[TMP0]]) +; IS__TUNIT_NPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]], align 64 +; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 +; IS__TUNIT_NPM-NEXT: ret void +; +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@avx512_legal512_prefer256_call_avx512_legal512_prefer256 +; IS__CGSCC_OPM-SAME: (<8 x i64>* nocapture nonnull writeonly align 2 dereferenceable(64) [[ARG:%.*]]) +; IS__CGSCC_OPM-NEXT: bb: +; IS__CGSCC_OPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32 +; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32 +; IS__CGSCC_OPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8* +; IS__CGSCC_OPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false) +; IS__CGSCC_OPM-NEXT: call fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal512_prefer256(<8 x i64>* nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64>* nofree nonnull readonly align 64 dereferenceable(64) [[TMP]]) +; IS__CGSCC_OPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]], align 64 +; IS__CGSCC_OPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 +; IS__CGSCC_OPM-NEXT: ret void +; +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@avx512_legal512_prefer256_call_avx512_legal512_prefer256 +; IS__CGSCC_NPM-SAME: (<8 x i64>* nocapture nonnull writeonly align 2 dereferenceable(64) [[ARG:%.*]]) +; IS__CGSCC_NPM-NEXT: bb: +; IS__CGSCC_NPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32 +; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32 +; IS__CGSCC_NPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8* +; IS__CGSCC_NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false) +; IS__CGSCC_NPM-NEXT: call fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal512_prefer256(<8 x i64>* noalias nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64>* noalias nofree nonnull readonly align 64 dereferenceable(64) [[TMP]]) +; IS__CGSCC_NPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]], align 64 +; IS__CGSCC_NPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 +; IS__CGSCC_NPM-NEXT: ret void ; bb: %tmp = alloca <8 x i64>, align 32 @@ -91,14 +184,22 @@ bb: ; This should promote define internal fastcc void @callee_avx512_legal512_prefer512_call_avx512_legal512_prefer256(<8 x i64>* %arg, <8 x i64>* readonly %arg1) #1 { -; CHECK-LABEL: define {{[^@]+}}@callee_avx512_legal512_prefer512_call_avx512_legal512_prefer256 -; CHECK-SAME: (<8 x i64>* noalias nocapture nofree nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64> [[TMP0:%.*]]) -; CHECK-NEXT: bb: -; CHECK-NEXT: [[ARG1_PRIV:%.*]] = alloca <8 x i64> -; CHECK-NEXT: store <8 x i64> [[TMP0]], <8 x i64>* [[ARG1_PRIV]] -; CHECK-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1_PRIV]], align 64 -; CHECK-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64 -; CHECK-NEXT: ret void +; +; NOT_TUNIT_NPM-LABEL: define {{[^@]+}}@callee_avx512_legal512_prefer512_call_avx512_legal512_prefer256 +; NOT_TUNIT_NPM-SAME: (<8 x i64>* nocapture nofree nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64>* nocapture nofree nonnull readonly align 64 dereferenceable(64) [[ARG1:%.*]]) +; NOT_TUNIT_NPM-NEXT: bb: +; NOT_TUNIT_NPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1]], align 64 +; NOT_TUNIT_NPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64 +; NOT_TUNIT_NPM-NEXT: ret void +; +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@callee_avx512_legal512_prefer512_call_avx512_legal512_prefer256 +; IS__TUNIT_NPM-SAME: (<8 x i64>* noalias nocapture nofree nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64> [[TMP0:%.*]]) +; IS__TUNIT_NPM-NEXT: bb: +; IS__TUNIT_NPM-NEXT: [[ARG1_PRIV:%.*]] = alloca <8 x i64> +; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP0]], <8 x i64>* [[ARG1_PRIV]] +; IS__TUNIT_NPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1_PRIV]], align 64 +; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64 +; IS__TUNIT_NPM-NEXT: ret void ; bb: %tmp = load <8 x i64>, <8 x i64>* %arg1 @@ -107,18 +208,55 @@ bb: } define void @avx512_legal512_prefer512_call_avx512_legal512_prefer256(<8 x i64>* %arg) #0 { -; CHECK-LABEL: define {{[^@]+}}@avx512_legal512_prefer512_call_avx512_legal512_prefer256 -; CHECK-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]]) -; CHECK-NEXT: bb: -; CHECK-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32 -; CHECK-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32 -; CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8* -; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull writeonly align 32 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false) -; CHECK-NEXT: [[TMP0:%.*]] = load <8 x i64>, <8 x i64>* [[TMP]], align 1 -; CHECK-NEXT: call fastcc void @callee_avx512_legal512_prefer512_call_avx512_legal512_prefer256(<8 x i64>* noalias nocapture nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64> [[TMP0]]) -; CHECK-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]], align 64 -; CHECK-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 -; CHECK-NEXT: ret void +; +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@avx512_legal512_prefer512_call_avx512_legal512_prefer256 +; IS__TUNIT_OPM-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]]) +; IS__TUNIT_OPM-NEXT: bb: +; IS__TUNIT_OPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32 +; IS__TUNIT_OPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32 +; IS__TUNIT_OPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8* +; IS__TUNIT_OPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false) +; IS__TUNIT_OPM-NEXT: call fastcc void @callee_avx512_legal512_prefer512_call_avx512_legal512_prefer256(<8 x i64>* nocapture nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64>* nocapture nofree nonnull readonly align 64 dereferenceable(64) [[TMP]]) +; IS__TUNIT_OPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]], align 64 +; IS__TUNIT_OPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 +; IS__TUNIT_OPM-NEXT: ret void +; +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@avx512_legal512_prefer512_call_avx512_legal512_prefer256 +; IS__TUNIT_NPM-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]]) +; IS__TUNIT_NPM-NEXT: bb: +; IS__TUNIT_NPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32 +; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32 +; IS__TUNIT_NPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8* +; IS__TUNIT_NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false) +; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load <8 x i64>, <8 x i64>* [[TMP]], align 1 +; IS__TUNIT_NPM-NEXT: call fastcc void @callee_avx512_legal512_prefer512_call_avx512_legal512_prefer256(<8 x i64>* noalias nocapture nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64> [[TMP0]]) +; IS__TUNIT_NPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]], align 64 +; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 +; IS__TUNIT_NPM-NEXT: ret void +; +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@avx512_legal512_prefer512_call_avx512_legal512_prefer256 +; IS__CGSCC_OPM-SAME: (<8 x i64>* nocapture nonnull writeonly align 2 dereferenceable(64) [[ARG:%.*]]) +; IS__CGSCC_OPM-NEXT: bb: +; IS__CGSCC_OPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32 +; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32 +; IS__CGSCC_OPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8* +; IS__CGSCC_OPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false) +; IS__CGSCC_OPM-NEXT: call fastcc void @callee_avx512_legal512_prefer512_call_avx512_legal512_prefer256(<8 x i64>* nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64>* nofree nonnull readonly align 64 dereferenceable(64) [[TMP]]) +; IS__CGSCC_OPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]], align 64 +; IS__CGSCC_OPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 +; IS__CGSCC_OPM-NEXT: ret void +; +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@avx512_legal512_prefer512_call_avx512_legal512_prefer256 +; IS__CGSCC_NPM-SAME: (<8 x i64>* nocapture nonnull writeonly align 2 dereferenceable(64) [[ARG:%.*]]) +; IS__CGSCC_NPM-NEXT: bb: +; IS__CGSCC_NPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32 +; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32 +; IS__CGSCC_NPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8* +; IS__CGSCC_NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false) +; IS__CGSCC_NPM-NEXT: call fastcc void @callee_avx512_legal512_prefer512_call_avx512_legal512_prefer256(<8 x i64>* noalias nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64>* noalias nofree nonnull readonly align 64 dereferenceable(64) [[TMP]]) +; IS__CGSCC_NPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]], align 64 +; IS__CGSCC_NPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 +; IS__CGSCC_NPM-NEXT: ret void ; bb: %tmp = alloca <8 x i64>, align 32 @@ -133,14 +271,22 @@ bb: ; This should promote define internal fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal512_prefer512(<8 x i64>* %arg, <8 x i64>* readonly %arg1) #0 { -; CHECK-LABEL: define {{[^@]+}}@callee_avx512_legal512_prefer256_call_avx512_legal512_prefer512 -; CHECK-SAME: (<8 x i64>* noalias nocapture nofree nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64> [[TMP0:%.*]]) -; CHECK-NEXT: bb: -; CHECK-NEXT: [[ARG1_PRIV:%.*]] = alloca <8 x i64> -; CHECK-NEXT: store <8 x i64> [[TMP0]], <8 x i64>* [[ARG1_PRIV]] -; CHECK-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1_PRIV]], align 64 -; CHECK-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64 -; CHECK-NEXT: ret void +; +; NOT_TUNIT_NPM-LABEL: define {{[^@]+}}@callee_avx512_legal512_prefer256_call_avx512_legal512_prefer512 +; NOT_TUNIT_NPM-SAME: (<8 x i64>* nocapture nofree nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64>* nocapture nofree nonnull readonly align 64 dereferenceable(64) [[ARG1:%.*]]) +; NOT_TUNIT_NPM-NEXT: bb: +; NOT_TUNIT_NPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1]], align 64 +; NOT_TUNIT_NPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64 +; NOT_TUNIT_NPM-NEXT: ret void +; +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@callee_avx512_legal512_prefer256_call_avx512_legal512_prefer512 +; IS__TUNIT_NPM-SAME: (<8 x i64>* noalias nocapture nofree nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64> [[TMP0:%.*]]) +; IS__TUNIT_NPM-NEXT: bb: +; IS__TUNIT_NPM-NEXT: [[ARG1_PRIV:%.*]] = alloca <8 x i64> +; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP0]], <8 x i64>* [[ARG1_PRIV]] +; IS__TUNIT_NPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1_PRIV]], align 64 +; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64 +; IS__TUNIT_NPM-NEXT: ret void ; bb: %tmp = load <8 x i64>, <8 x i64>* %arg1 @@ -149,18 +295,55 @@ bb: } define void @avx512_legal512_prefer256_call_avx512_legal512_prefer512(<8 x i64>* %arg) #1 { -; CHECK-LABEL: define {{[^@]+}}@avx512_legal512_prefer256_call_avx512_legal512_prefer512 -; CHECK-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]]) -; CHECK-NEXT: bb: -; CHECK-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32 -; CHECK-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32 -; CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8* -; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull writeonly align 32 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false) -; CHECK-NEXT: [[TMP0:%.*]] = load <8 x i64>, <8 x i64>* [[TMP]], align 1 -; CHECK-NEXT: call fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal512_prefer512(<8 x i64>* noalias nocapture nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64> [[TMP0]]) -; CHECK-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]], align 64 -; CHECK-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 -; CHECK-NEXT: ret void +; +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@avx512_legal512_prefer256_call_avx512_legal512_prefer512 +; IS__TUNIT_OPM-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]]) +; IS__TUNIT_OPM-NEXT: bb: +; IS__TUNIT_OPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32 +; IS__TUNIT_OPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32 +; IS__TUNIT_OPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8* +; IS__TUNIT_OPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false) +; IS__TUNIT_OPM-NEXT: call fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal512_prefer512(<8 x i64>* nocapture nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64>* nocapture nofree nonnull readonly align 64 dereferenceable(64) [[TMP]]) +; IS__TUNIT_OPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]], align 64 +; IS__TUNIT_OPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 +; IS__TUNIT_OPM-NEXT: ret void +; +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@avx512_legal512_prefer256_call_avx512_legal512_prefer512 +; IS__TUNIT_NPM-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]]) +; IS__TUNIT_NPM-NEXT: bb: +; IS__TUNIT_NPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32 +; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32 +; IS__TUNIT_NPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8* +; IS__TUNIT_NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false) +; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load <8 x i64>, <8 x i64>* [[TMP]], align 1 +; IS__TUNIT_NPM-NEXT: call fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal512_prefer512(<8 x i64>* noalias nocapture nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64> [[TMP0]]) +; IS__TUNIT_NPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]], align 64 +; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 +; IS__TUNIT_NPM-NEXT: ret void +; +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@avx512_legal512_prefer256_call_avx512_legal512_prefer512 +; IS__CGSCC_OPM-SAME: (<8 x i64>* nocapture nonnull writeonly align 2 dereferenceable(64) [[ARG:%.*]]) +; IS__CGSCC_OPM-NEXT: bb: +; IS__CGSCC_OPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32 +; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32 +; IS__CGSCC_OPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8* +; IS__CGSCC_OPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false) +; IS__CGSCC_OPM-NEXT: call fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal512_prefer512(<8 x i64>* nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64>* nofree nonnull readonly align 64 dereferenceable(64) [[TMP]]) +; IS__CGSCC_OPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]], align 64 +; IS__CGSCC_OPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 +; IS__CGSCC_OPM-NEXT: ret void +; +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@avx512_legal512_prefer256_call_avx512_legal512_prefer512 +; IS__CGSCC_NPM-SAME: (<8 x i64>* nocapture nonnull writeonly align 2 dereferenceable(64) [[ARG:%.*]]) +; IS__CGSCC_NPM-NEXT: bb: +; IS__CGSCC_NPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32 +; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32 +; IS__CGSCC_NPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8* +; IS__CGSCC_NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false) +; IS__CGSCC_NPM-NEXT: call fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal512_prefer512(<8 x i64>* noalias nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64>* noalias nofree nonnull readonly align 64 dereferenceable(64) [[TMP]]) +; IS__CGSCC_NPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]], align 64 +; IS__CGSCC_NPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 +; IS__CGSCC_NPM-NEXT: ret void ; bb: %tmp = alloca <8 x i64>, align 32 @@ -175,12 +358,20 @@ bb: ; This should not promote define internal fastcc void @callee_avx512_legal256_prefer256_call_avx512_legal512_prefer256(<8 x i64>* %arg, <8 x i64>* readonly %arg1) #1 { -; CHECK-LABEL: define {{[^@]+}}@callee_avx512_legal256_prefer256_call_avx512_legal512_prefer256 -; CHECK-SAME: (<8 x i64>* noalias nocapture nofree nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64>* noalias nocapture nofree nonnull readonly align 64 dereferenceable(64) [[ARG1:%.*]]) -; CHECK-NEXT: bb: -; CHECK-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1]], align 64 -; CHECK-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64 -; CHECK-NEXT: ret void +; +; NOT_TUNIT_NPM-LABEL: define {{[^@]+}}@callee_avx512_legal256_prefer256_call_avx512_legal512_prefer256 +; NOT_TUNIT_NPM-SAME: (<8 x i64>* nocapture nofree nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64>* nocapture nofree nonnull readonly align 64 dereferenceable(64) [[ARG1:%.*]]) +; NOT_TUNIT_NPM-NEXT: bb: +; NOT_TUNIT_NPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1]], align 64 +; NOT_TUNIT_NPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64 +; NOT_TUNIT_NPM-NEXT: ret void +; +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@callee_avx512_legal256_prefer256_call_avx512_legal512_prefer256 +; IS__TUNIT_NPM-SAME: (<8 x i64>* noalias nocapture nofree nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64>* noalias nocapture nofree nonnull readonly align 64 dereferenceable(64) [[ARG1:%.*]]) +; IS__TUNIT_NPM-NEXT: bb: +; IS__TUNIT_NPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1]], align 64 +; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64 +; IS__TUNIT_NPM-NEXT: ret void ; bb: %tmp = load <8 x i64>, <8 x i64>* %arg1 @@ -189,17 +380,54 @@ bb: } define void @avx512_legal256_prefer256_call_avx512_legal512_prefer256(<8 x i64>* %arg) #2 { -; CHECK-LABEL: define {{[^@]+}}@avx512_legal256_prefer256_call_avx512_legal512_prefer256 -; CHECK-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]]) -; CHECK-NEXT: bb: -; CHECK-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32 -; CHECK-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32 -; CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8* -; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull writeonly align 32 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false) -; CHECK-NEXT: call fastcc void @callee_avx512_legal256_prefer256_call_avx512_legal512_prefer256(<8 x i64>* noalias nocapture nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64>* noalias nocapture nofree nonnull readonly align 64 dereferenceable(64) [[TMP]]) -; CHECK-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]], align 64 -; CHECK-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 -; CHECK-NEXT: ret void +; +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@avx512_legal256_prefer256_call_avx512_legal512_prefer256 +; IS__TUNIT_OPM-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]]) +; IS__TUNIT_OPM-NEXT: bb: +; IS__TUNIT_OPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32 +; IS__TUNIT_OPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32 +; IS__TUNIT_OPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8* +; IS__TUNIT_OPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false) +; IS__TUNIT_OPM-NEXT: call fastcc void @callee_avx512_legal256_prefer256_call_avx512_legal512_prefer256(<8 x i64>* nocapture nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64>* nocapture nofree nonnull readonly align 64 dereferenceable(64) [[TMP]]) +; IS__TUNIT_OPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]], align 64 +; IS__TUNIT_OPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 +; IS__TUNIT_OPM-NEXT: ret void +; +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@avx512_legal256_prefer256_call_avx512_legal512_prefer256 +; IS__TUNIT_NPM-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]]) +; IS__TUNIT_NPM-NEXT: bb: +; IS__TUNIT_NPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32 +; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32 +; IS__TUNIT_NPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8* +; IS__TUNIT_NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false) +; IS__TUNIT_NPM-NEXT: call fastcc void @callee_avx512_legal256_prefer256_call_avx512_legal512_prefer256(<8 x i64>* noalias nocapture nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64>* noalias nocapture nofree nonnull readonly align 64 dereferenceable(64) [[TMP]]) +; IS__TUNIT_NPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]], align 64 +; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 +; IS__TUNIT_NPM-NEXT: ret void +; +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@avx512_legal256_prefer256_call_avx512_legal512_prefer256 +; IS__CGSCC_OPM-SAME: (<8 x i64>* nocapture nonnull writeonly align 2 dereferenceable(64) [[ARG:%.*]]) +; IS__CGSCC_OPM-NEXT: bb: +; IS__CGSCC_OPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32 +; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32 +; IS__CGSCC_OPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8* +; IS__CGSCC_OPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false) +; IS__CGSCC_OPM-NEXT: call fastcc void @callee_avx512_legal256_prefer256_call_avx512_legal512_prefer256(<8 x i64>* nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64>* nofree nonnull readonly align 64 dereferenceable(64) [[TMP]]) +; IS__CGSCC_OPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]], align 64 +; IS__CGSCC_OPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 +; IS__CGSCC_OPM-NEXT: ret void +; +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@avx512_legal256_prefer256_call_avx512_legal512_prefer256 +; IS__CGSCC_NPM-SAME: (<8 x i64>* nocapture nonnull writeonly align 2 dereferenceable(64) [[ARG:%.*]]) +; IS__CGSCC_NPM-NEXT: bb: +; IS__CGSCC_NPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32 +; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32 +; IS__CGSCC_NPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8* +; IS__CGSCC_NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false) +; IS__CGSCC_NPM-NEXT: call fastcc void @callee_avx512_legal256_prefer256_call_avx512_legal512_prefer256(<8 x i64>* noalias nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64>* noalias nofree nonnull readonly align 64 dereferenceable(64) [[TMP]]) +; IS__CGSCC_NPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]], align 64 +; IS__CGSCC_NPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 +; IS__CGSCC_NPM-NEXT: ret void ; bb: %tmp = alloca <8 x i64>, align 32 @@ -214,12 +442,20 @@ bb: ; This should not promote define internal fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal256_prefer256(<8 x i64>* %arg, <8 x i64>* readonly %arg1) #2 { -; CHECK-LABEL: define {{[^@]+}}@callee_avx512_legal512_prefer256_call_avx512_legal256_prefer256 -; CHECK-SAME: (<8 x i64>* noalias nocapture nofree nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64>* noalias nocapture nofree nonnull readonly align 64 dereferenceable(64) [[ARG1:%.*]]) -; CHECK-NEXT: bb: -; CHECK-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1]], align 64 -; CHECK-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64 -; CHECK-NEXT: ret void +; +; NOT_TUNIT_NPM-LABEL: define {{[^@]+}}@callee_avx512_legal512_prefer256_call_avx512_legal256_prefer256 +; NOT_TUNIT_NPM-SAME: (<8 x i64>* nocapture nofree nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64>* nocapture nofree nonnull readonly align 64 dereferenceable(64) [[ARG1:%.*]]) +; NOT_TUNIT_NPM-NEXT: bb: +; NOT_TUNIT_NPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1]], align 64 +; NOT_TUNIT_NPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64 +; NOT_TUNIT_NPM-NEXT: ret void +; +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@callee_avx512_legal512_prefer256_call_avx512_legal256_prefer256 +; IS__TUNIT_NPM-SAME: (<8 x i64>* noalias nocapture nofree nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64>* noalias nocapture nofree nonnull readonly align 64 dereferenceable(64) [[ARG1:%.*]]) +; IS__TUNIT_NPM-NEXT: bb: +; IS__TUNIT_NPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1]], align 64 +; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64 +; IS__TUNIT_NPM-NEXT: ret void ; bb: %tmp = load <8 x i64>, <8 x i64>* %arg1 @@ -228,17 +464,54 @@ bb: } define void @avx512_legal512_prefer256_call_avx512_legal256_prefer256(<8 x i64>* %arg) #1 { -; CHECK-LABEL: define {{[^@]+}}@avx512_legal512_prefer256_call_avx512_legal256_prefer256 -; CHECK-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]]) -; CHECK-NEXT: bb: -; CHECK-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32 -; CHECK-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32 -; CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8* -; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull writeonly align 32 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false) -; CHECK-NEXT: call fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal256_prefer256(<8 x i64>* noalias nocapture nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64>* noalias nocapture nofree nonnull readonly align 64 dereferenceable(64) [[TMP]]) -; CHECK-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]], align 64 -; CHECK-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 -; CHECK-NEXT: ret void +; +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@avx512_legal512_prefer256_call_avx512_legal256_prefer256 +; IS__TUNIT_OPM-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]]) +; IS__TUNIT_OPM-NEXT: bb: +; IS__TUNIT_OPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32 +; IS__TUNIT_OPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32 +; IS__TUNIT_OPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8* +; IS__TUNIT_OPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false) +; IS__TUNIT_OPM-NEXT: call fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal256_prefer256(<8 x i64>* nocapture nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64>* nocapture nofree nonnull readonly align 64 dereferenceable(64) [[TMP]]) +; IS__TUNIT_OPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]], align 64 +; IS__TUNIT_OPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 +; IS__TUNIT_OPM-NEXT: ret void +; +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@avx512_legal512_prefer256_call_avx512_legal256_prefer256 +; IS__TUNIT_NPM-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]]) +; IS__TUNIT_NPM-NEXT: bb: +; IS__TUNIT_NPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32 +; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32 +; IS__TUNIT_NPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8* +; IS__TUNIT_NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false) +; IS__TUNIT_NPM-NEXT: call fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal256_prefer256(<8 x i64>* noalias nocapture nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64>* noalias nocapture nofree nonnull readonly align 64 dereferenceable(64) [[TMP]]) +; IS__TUNIT_NPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]], align 64 +; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 +; IS__TUNIT_NPM-NEXT: ret void +; +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@avx512_legal512_prefer256_call_avx512_legal256_prefer256 +; IS__CGSCC_OPM-SAME: (<8 x i64>* nocapture nonnull writeonly align 2 dereferenceable(64) [[ARG:%.*]]) +; IS__CGSCC_OPM-NEXT: bb: +; IS__CGSCC_OPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32 +; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32 +; IS__CGSCC_OPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8* +; IS__CGSCC_OPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false) +; IS__CGSCC_OPM-NEXT: call fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal256_prefer256(<8 x i64>* nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64>* nofree nonnull readonly align 64 dereferenceable(64) [[TMP]]) +; IS__CGSCC_OPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]], align 64 +; IS__CGSCC_OPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 +; IS__CGSCC_OPM-NEXT: ret void +; +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@avx512_legal512_prefer256_call_avx512_legal256_prefer256 +; IS__CGSCC_NPM-SAME: (<8 x i64>* nocapture nonnull writeonly align 2 dereferenceable(64) [[ARG:%.*]]) +; IS__CGSCC_NPM-NEXT: bb: +; IS__CGSCC_NPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32 +; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32 +; IS__CGSCC_NPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8* +; IS__CGSCC_NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false) +; IS__CGSCC_NPM-NEXT: call fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal256_prefer256(<8 x i64>* noalias nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64>* noalias nofree nonnull readonly align 64 dereferenceable(64) [[TMP]]) +; IS__CGSCC_NPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]], align 64 +; IS__CGSCC_NPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 +; IS__CGSCC_NPM-NEXT: ret void ; bb: %tmp = alloca <8 x i64>, align 32 @@ -253,14 +526,22 @@ bb: ; This should promote define internal fastcc void @callee_avx2_legal256_prefer256_call_avx2_legal512_prefer256(<8 x i64>* %arg, <8 x i64>* readonly %arg1) #3 { -; CHECK-LABEL: define {{[^@]+}}@callee_avx2_legal256_prefer256_call_avx2_legal512_prefer256 -; CHECK-SAME: (<8 x i64>* noalias nocapture nofree nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64> [[TMP0:%.*]]) -; CHECK-NEXT: bb: -; CHECK-NEXT: [[ARG1_PRIV:%.*]] = alloca <8 x i64> -; CHECK-NEXT: store <8 x i64> [[TMP0]], <8 x i64>* [[ARG1_PRIV]] -; CHECK-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1_PRIV]], align 64 -; CHECK-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64 -; CHECK-NEXT: ret void +; +; NOT_TUNIT_NPM-LABEL: define {{[^@]+}}@callee_avx2_legal256_prefer256_call_avx2_legal512_prefer256 +; NOT_TUNIT_NPM-SAME: (<8 x i64>* nocapture nofree nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64>* nocapture nofree nonnull readonly align 64 dereferenceable(64) [[ARG1:%.*]]) +; NOT_TUNIT_NPM-NEXT: bb: +; NOT_TUNIT_NPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1]], align 64 +; NOT_TUNIT_NPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64 +; NOT_TUNIT_NPM-NEXT: ret void +; +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@callee_avx2_legal256_prefer256_call_avx2_legal512_prefer256 +; IS__TUNIT_NPM-SAME: (<8 x i64>* noalias nocapture nofree nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64> [[TMP0:%.*]]) +; IS__TUNIT_NPM-NEXT: bb: +; IS__TUNIT_NPM-NEXT: [[ARG1_PRIV:%.*]] = alloca <8 x i64> +; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP0]], <8 x i64>* [[ARG1_PRIV]] +; IS__TUNIT_NPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1_PRIV]], align 64 +; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64 +; IS__TUNIT_NPM-NEXT: ret void ; bb: %tmp = load <8 x i64>, <8 x i64>* %arg1 @@ -269,18 +550,55 @@ bb: } define void @avx2_legal256_prefer256_call_avx2_legal512_prefer256(<8 x i64>* %arg) #4 { -; CHECK-LABEL: define {{[^@]+}}@avx2_legal256_prefer256_call_avx2_legal512_prefer256 -; CHECK-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]]) -; CHECK-NEXT: bb: -; CHECK-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32 -; CHECK-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32 -; CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8* -; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull writeonly align 32 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false) -; CHECK-NEXT: [[TMP0:%.*]] = load <8 x i64>, <8 x i64>* [[TMP]], align 1 -; CHECK-NEXT: call fastcc void @callee_avx2_legal256_prefer256_call_avx2_legal512_prefer256(<8 x i64>* noalias nocapture nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64> [[TMP0]]) -; CHECK-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]], align 64 -; CHECK-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 -; CHECK-NEXT: ret void +; +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@avx2_legal256_prefer256_call_avx2_legal512_prefer256 +; IS__TUNIT_OPM-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]]) +; IS__TUNIT_OPM-NEXT: bb: +; IS__TUNIT_OPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32 +; IS__TUNIT_OPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32 +; IS__TUNIT_OPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8* +; IS__TUNIT_OPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false) +; IS__TUNIT_OPM-NEXT: call fastcc void @callee_avx2_legal256_prefer256_call_avx2_legal512_prefer256(<8 x i64>* nocapture nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64>* nocapture nofree nonnull readonly align 64 dereferenceable(64) [[TMP]]) +; IS__TUNIT_OPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]], align 64 +; IS__TUNIT_OPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 +; IS__TUNIT_OPM-NEXT: ret void +; +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@avx2_legal256_prefer256_call_avx2_legal512_prefer256 +; IS__TUNIT_NPM-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]]) +; IS__TUNIT_NPM-NEXT: bb: +; IS__TUNIT_NPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32 +; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32 +; IS__TUNIT_NPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8* +; IS__TUNIT_NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false) +; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load <8 x i64>, <8 x i64>* [[TMP]], align 1 +; IS__TUNIT_NPM-NEXT: call fastcc void @callee_avx2_legal256_prefer256_call_avx2_legal512_prefer256(<8 x i64>* noalias nocapture nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64> [[TMP0]]) +; IS__TUNIT_NPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]], align 64 +; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 +; IS__TUNIT_NPM-NEXT: ret void +; +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@avx2_legal256_prefer256_call_avx2_legal512_prefer256 +; IS__CGSCC_OPM-SAME: (<8 x i64>* nocapture nonnull writeonly align 2 dereferenceable(64) [[ARG:%.*]]) +; IS__CGSCC_OPM-NEXT: bb: +; IS__CGSCC_OPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32 +; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32 +; IS__CGSCC_OPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8* +; IS__CGSCC_OPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false) +; IS__CGSCC_OPM-NEXT: call fastcc void @callee_avx2_legal256_prefer256_call_avx2_legal512_prefer256(<8 x i64>* nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64>* nofree nonnull readonly align 64 dereferenceable(64) [[TMP]]) +; IS__CGSCC_OPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]], align 64 +; IS__CGSCC_OPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 +; IS__CGSCC_OPM-NEXT: ret void +; +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@avx2_legal256_prefer256_call_avx2_legal512_prefer256 +; IS__CGSCC_NPM-SAME: (<8 x i64>* nocapture nonnull writeonly align 2 dereferenceable(64) [[ARG:%.*]]) +; IS__CGSCC_NPM-NEXT: bb: +; IS__CGSCC_NPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32 +; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32 +; IS__CGSCC_NPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8* +; IS__CGSCC_NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false) +; IS__CGSCC_NPM-NEXT: call fastcc void @callee_avx2_legal256_prefer256_call_avx2_legal512_prefer256(<8 x i64>* noalias nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64>* noalias nofree nonnull readonly align 64 dereferenceable(64) [[TMP]]) +; IS__CGSCC_NPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]], align 64 +; IS__CGSCC_NPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 +; IS__CGSCC_NPM-NEXT: ret void ; bb: %tmp = alloca <8 x i64>, align 32 @@ -295,14 +613,22 @@ bb: ; This should promote define internal fastcc void @callee_avx2_legal512_prefer256_call_avx2_legal256_prefer256(<8 x i64>* %arg, <8 x i64>* readonly %arg1) #4 { -; CHECK-LABEL: define {{[^@]+}}@callee_avx2_legal512_prefer256_call_avx2_legal256_prefer256 -; CHECK-SAME: (<8 x i64>* noalias nocapture nofree nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64> [[TMP0:%.*]]) -; CHECK-NEXT: bb: -; CHECK-NEXT: [[ARG1_PRIV:%.*]] = alloca <8 x i64> -; CHECK-NEXT: store <8 x i64> [[TMP0]], <8 x i64>* [[ARG1_PRIV]] -; CHECK-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1_PRIV]], align 64 -; CHECK-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64 -; CHECK-NEXT: ret void +; +; NOT_TUNIT_NPM-LABEL: define {{[^@]+}}@callee_avx2_legal512_prefer256_call_avx2_legal256_prefer256 +; NOT_TUNIT_NPM-SAME: (<8 x i64>* nocapture nofree nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64>* nocapture nofree nonnull readonly align 64 dereferenceable(64) [[ARG1:%.*]]) +; NOT_TUNIT_NPM-NEXT: bb: +; NOT_TUNIT_NPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1]], align 64 +; NOT_TUNIT_NPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64 +; NOT_TUNIT_NPM-NEXT: ret void +; +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@callee_avx2_legal512_prefer256_call_avx2_legal256_prefer256 +; IS__TUNIT_NPM-SAME: (<8 x i64>* noalias nocapture nofree nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64> [[TMP0:%.*]]) +; IS__TUNIT_NPM-NEXT: bb: +; IS__TUNIT_NPM-NEXT: [[ARG1_PRIV:%.*]] = alloca <8 x i64> +; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP0]], <8 x i64>* [[ARG1_PRIV]] +; IS__TUNIT_NPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1_PRIV]], align 64 +; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64 +; IS__TUNIT_NPM-NEXT: ret void ; bb: %tmp = load <8 x i64>, <8 x i64>* %arg1 @@ -311,18 +637,55 @@ bb: } define void @avx2_legal512_prefer256_call_avx2_legal256_prefer256(<8 x i64>* %arg) #3 { -; CHECK-LABEL: define {{[^@]+}}@avx2_legal512_prefer256_call_avx2_legal256_prefer256 -; CHECK-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]]) -; CHECK-NEXT: bb: -; CHECK-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32 -; CHECK-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32 -; CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8* -; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull writeonly align 32 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false) -; CHECK-NEXT: [[TMP0:%.*]] = load <8 x i64>, <8 x i64>* [[TMP]], align 1 -; CHECK-NEXT: call fastcc void @callee_avx2_legal512_prefer256_call_avx2_legal256_prefer256(<8 x i64>* noalias nocapture nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64> [[TMP0]]) -; CHECK-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]], align 64 -; CHECK-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 -; CHECK-NEXT: ret void +; +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@avx2_legal512_prefer256_call_avx2_legal256_prefer256 +; IS__TUNIT_OPM-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]]) +; IS__TUNIT_OPM-NEXT: bb: +; IS__TUNIT_OPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32 +; IS__TUNIT_OPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32 +; IS__TUNIT_OPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8* +; IS__TUNIT_OPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false) +; IS__TUNIT_OPM-NEXT: call fastcc void @callee_avx2_legal512_prefer256_call_avx2_legal256_prefer256(<8 x i64>* nocapture nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64>* nocapture nofree nonnull readonly align 64 dereferenceable(64) [[TMP]]) +; IS__TUNIT_OPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]], align 64 +; IS__TUNIT_OPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 +; IS__TUNIT_OPM-NEXT: ret void +; +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@avx2_legal512_prefer256_call_avx2_legal256_prefer256 +; IS__TUNIT_NPM-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]]) +; IS__TUNIT_NPM-NEXT: bb: +; IS__TUNIT_NPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32 +; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32 +; IS__TUNIT_NPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8* +; IS__TUNIT_NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false) +; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load <8 x i64>, <8 x i64>* [[TMP]], align 1 +; IS__TUNIT_NPM-NEXT: call fastcc void @callee_avx2_legal512_prefer256_call_avx2_legal256_prefer256(<8 x i64>* noalias nocapture nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64> [[TMP0]]) +; IS__TUNIT_NPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]], align 64 +; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 +; IS__TUNIT_NPM-NEXT: ret void +; +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@avx2_legal512_prefer256_call_avx2_legal256_prefer256 +; IS__CGSCC_OPM-SAME: (<8 x i64>* nocapture nonnull writeonly align 2 dereferenceable(64) [[ARG:%.*]]) +; IS__CGSCC_OPM-NEXT: bb: +; IS__CGSCC_OPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32 +; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32 +; IS__CGSCC_OPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8* +; IS__CGSCC_OPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false) +; IS__CGSCC_OPM-NEXT: call fastcc void @callee_avx2_legal512_prefer256_call_avx2_legal256_prefer256(<8 x i64>* nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64>* nofree nonnull readonly align 64 dereferenceable(64) [[TMP]]) +; IS__CGSCC_OPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]], align 64 +; IS__CGSCC_OPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 +; IS__CGSCC_OPM-NEXT: ret void +; +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@avx2_legal512_prefer256_call_avx2_legal256_prefer256 +; IS__CGSCC_NPM-SAME: (<8 x i64>* nocapture nonnull writeonly align 2 dereferenceable(64) [[ARG:%.*]]) +; IS__CGSCC_NPM-NEXT: bb: +; IS__CGSCC_NPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32 +; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32 +; IS__CGSCC_NPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8* +; IS__CGSCC_NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false) +; IS__CGSCC_NPM-NEXT: call fastcc void @callee_avx2_legal512_prefer256_call_avx2_legal256_prefer256(<8 x i64>* noalias nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64>* noalias nofree nonnull readonly align 64 dereferenceable(64) [[TMP]]) +; IS__CGSCC_NPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]], align 64 +; IS__CGSCC_NPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 +; IS__CGSCC_NPM-NEXT: ret void ; bb: %tmp = alloca <8 x i64>, align 32 diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/thiscall.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/thiscall.ll index d9f3681ba4ab..ec32b24e1b9a 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/thiscall.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/thiscall.ll @@ -4,8 +4,10 @@ ; we don't do that anymore. It also verifies that the combination of ; globalopt and argpromotion is able to optimize the call safely. ; -; RUN: opt -S -argpromotion %s | FileCheck %s --check-prefix=ARGPROMOTION -; RUN: opt -S -globalopt -argpromotion %s | FileCheck %s --check-prefix=GLOBALOPT_ARGPROMOTION +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32" target triple = "i386-pc-windows-msvc19.11.0" @@ -13,25 +15,25 @@ target triple = "i386-pc-windows-msvc19.11.0" %struct.a = type { i8 } define internal x86_thiscallcc void @internalfun(%struct.a* %this, <{ %struct.a }>* inalloca) { -; ARGPROMOTION-LABEL: define {{[^@]+}}@internalfun -; ARGPROMOTION-SAME: (%struct.a* [[THIS:%.*]], <{ [[STRUCT_A:%.*]] }>* inalloca [[TMP0:%.*]]) -; ARGPROMOTION-NEXT: entry: -; ARGPROMOTION-NEXT: [[A:%.*]] = getelementptr inbounds <{ [[STRUCT_A]] }>, <{ [[STRUCT_A]] }>* [[TMP0]], i32 0, i32 0 -; ARGPROMOTION-NEXT: [[ARGMEM:%.*]] = alloca inalloca <{ [[STRUCT_A]] }>, align 4 -; ARGPROMOTION-NEXT: [[TMP1:%.*]] = getelementptr inbounds <{ [[STRUCT_A]] }>, <{ [[STRUCT_A]] }>* [[ARGMEM]], i32 0, i32 0 -; ARGPROMOTION-NEXT: [[CALL:%.*]] = call x86_thiscallcc %struct.a* @copy_ctor(%struct.a* [[TMP1]], %struct.a* dereferenceable(1) [[A]]) -; ARGPROMOTION-NEXT: call void @ext(<{ [[STRUCT_A]] }>* inalloca [[ARGMEM]]) -; ARGPROMOTION-NEXT: ret void +; IS__TUNIT____-LABEL: define {{[^@]+}}@internalfun +; IS__TUNIT____-SAME: (%struct.a* noalias nocapture nofree readnone [[THIS:%.*]], <{ [[STRUCT_A:%.*]] }>* inalloca nonnull align 4 dereferenceable(1) [[TMP0:%.*]]) +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: [[A:%.*]] = getelementptr inbounds <{ [[STRUCT_A]] }>, <{ [[STRUCT_A]] }>* [[TMP0]], i32 0, i32 0 +; IS__TUNIT____-NEXT: [[ARGMEM:%.*]] = alloca inalloca <{ [[STRUCT_A]] }>, align 4 +; IS__TUNIT____-NEXT: [[TMP1:%.*]] = getelementptr inbounds <{ [[STRUCT_A]] }>, <{ [[STRUCT_A]] }>* [[ARGMEM]], i32 0, i32 0 +; IS__TUNIT____-NEXT: [[CALL:%.*]] = call x86_thiscallcc %struct.a* @copy_ctor(%struct.a* nonnull align 4 dereferenceable(1) [[TMP1]], %struct.a* nonnull align 4 dereferenceable(1) [[A]]) +; IS__TUNIT____-NEXT: call void @ext(<{ [[STRUCT_A]] }>* inalloca nonnull align 4 dereferenceable(1) [[ARGMEM]]) +; IS__TUNIT____-NEXT: ret void ; -; GLOBALOPT_ARGPROMOTION-LABEL: define {{[^@]+}}@internalfun -; GLOBALOPT_ARGPROMOTION-SAME: (<{ [[STRUCT_A:%.*]] }>* [[TMP0:%.*]]) unnamed_addr -; GLOBALOPT_ARGPROMOTION-NEXT: entry: -; GLOBALOPT_ARGPROMOTION-NEXT: [[A:%.*]] = getelementptr inbounds <{ [[STRUCT_A]] }>, <{ [[STRUCT_A]] }>* [[TMP0]], i32 0, i32 0 -; GLOBALOPT_ARGPROMOTION-NEXT: [[ARGMEM:%.*]] = alloca inalloca <{ [[STRUCT_A]] }>, align 4 -; GLOBALOPT_ARGPROMOTION-NEXT: [[TMP1:%.*]] = getelementptr inbounds <{ [[STRUCT_A]] }>, <{ [[STRUCT_A]] }>* [[ARGMEM]], i32 0, i32 0 -; GLOBALOPT_ARGPROMOTION-NEXT: [[CALL:%.*]] = call x86_thiscallcc %struct.a* @copy_ctor(%struct.a* [[TMP1]], %struct.a* dereferenceable(1) [[A]]) -; GLOBALOPT_ARGPROMOTION-NEXT: call void @ext(<{ [[STRUCT_A]] }>* inalloca [[ARGMEM]]) -; GLOBALOPT_ARGPROMOTION-NEXT: ret void +; IS__CGSCC____-LABEL: define {{[^@]+}}@internalfun +; IS__CGSCC____-SAME: (%struct.a* nocapture nofree readnone [[THIS:%.*]], <{ [[STRUCT_A:%.*]] }>* inalloca nonnull dereferenceable(1) [[TMP0:%.*]]) +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: [[A:%.*]] = getelementptr inbounds <{ [[STRUCT_A]] }>, <{ [[STRUCT_A]] }>* [[TMP0]], i32 0, i32 0 +; IS__CGSCC____-NEXT: [[ARGMEM:%.*]] = alloca inalloca <{ [[STRUCT_A]] }>, align 4 +; IS__CGSCC____-NEXT: [[TMP1:%.*]] = getelementptr inbounds <{ [[STRUCT_A]] }>, <{ [[STRUCT_A]] }>* [[ARGMEM]], i32 0, i32 0 +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call x86_thiscallcc %struct.a* @copy_ctor(%struct.a* nonnull align 4 dereferenceable(1) [[TMP1]], %struct.a* nonnull dereferenceable(1) [[A]]) +; IS__CGSCC____-NEXT: call void @ext(<{ [[STRUCT_A]] }>* inalloca nonnull align 4 dereferenceable(1) [[ARGMEM]]) +; IS__CGSCC____-NEXT: ret void ; entry: %a = getelementptr inbounds <{ %struct.a }>, <{ %struct.a }>* %0, i32 0, i32 0 @@ -44,21 +46,21 @@ entry: ; This is here to ensure @internalfun is live. define void @exportedfun(%struct.a* %a) { -; ARGPROMOTION-LABEL: define {{[^@]+}}@exportedfun -; ARGPROMOTION-SAME: (%struct.a* [[A:%.*]]) -; ARGPROMOTION-NEXT: [[INALLOCA_SAVE:%.*]] = tail call i8* @llvm.stacksave() -; ARGPROMOTION-NEXT: [[ARGMEM:%.*]] = alloca inalloca <{ [[STRUCT_A:%.*]] }>, align 4 -; ARGPROMOTION-NEXT: call x86_thiscallcc void @internalfun(%struct.a* [[A]], <{ [[STRUCT_A]] }>* inalloca [[ARGMEM]]) -; ARGPROMOTION-NEXT: call void @llvm.stackrestore(i8* [[INALLOCA_SAVE]]) -; ARGPROMOTION-NEXT: ret void +; IS__TUNIT____-LABEL: define {{[^@]+}}@exportedfun +; IS__TUNIT____-SAME: (%struct.a* nocapture nofree readnone [[A:%.*]]) +; IS__TUNIT____-NEXT: [[INALLOCA_SAVE:%.*]] = tail call i8* @llvm.stacksave() +; IS__TUNIT____-NEXT: [[ARGMEM:%.*]] = alloca inalloca <{ [[STRUCT_A:%.*]] }>, align 4 +; IS__TUNIT____-NEXT: call x86_thiscallcc void @internalfun(%struct.a* noalias nofree readnone undef, <{ [[STRUCT_A]] }>* inalloca nonnull align 4 dereferenceable(1) [[ARGMEM]]) +; IS__TUNIT____-NEXT: call void @llvm.stackrestore(i8* [[INALLOCA_SAVE]]) +; IS__TUNIT____-NEXT: ret void ; -; GLOBALOPT_ARGPROMOTION-LABEL: define {{[^@]+}}@exportedfun -; GLOBALOPT_ARGPROMOTION-SAME: (%struct.a* [[A:%.*]]) local_unnamed_addr -; GLOBALOPT_ARGPROMOTION-NEXT: [[INALLOCA_SAVE:%.*]] = tail call i8* @llvm.stacksave() -; GLOBALOPT_ARGPROMOTION-NEXT: [[ARGMEM:%.*]] = alloca inalloca <{ [[STRUCT_A:%.*]] }>, align 4 -; GLOBALOPT_ARGPROMOTION-NEXT: call fastcc void @internalfun(<{ [[STRUCT_A]] }>* [[ARGMEM]]) -; GLOBALOPT_ARGPROMOTION-NEXT: call void @llvm.stackrestore(i8* [[INALLOCA_SAVE]]) -; GLOBALOPT_ARGPROMOTION-NEXT: ret void +; IS__CGSCC____-LABEL: define {{[^@]+}}@exportedfun +; IS__CGSCC____-SAME: (%struct.a* nocapture nofree readnone [[A:%.*]]) +; IS__CGSCC____-NEXT: [[INALLOCA_SAVE:%.*]] = tail call i8* @llvm.stacksave() +; IS__CGSCC____-NEXT: [[ARGMEM:%.*]] = alloca inalloca <{ [[STRUCT_A:%.*]] }>, align 4 +; IS__CGSCC____-NEXT: call x86_thiscallcc void @internalfun(%struct.a* noalias nocapture nofree readnone [[A]], <{ [[STRUCT_A]] }>* inalloca nonnull align 4 dereferenceable(1) [[ARGMEM]]) +; IS__CGSCC____-NEXT: call void @llvm.stackrestore(i8* [[INALLOCA_SAVE]]) +; IS__CGSCC____-NEXT: ret void ; %inalloca.save = tail call i8* @llvm.stacksave() %argmem = alloca inalloca <{ %struct.a }>, align 4 diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/aggregate-promote.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/aggregate-promote.ll index dc71592e4f9a..be64712b02bb 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/aggregate-promote.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/aggregate-promote.ll @@ -1,14 +1,20 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes -; RUN: opt -disable-output -passes=attributor -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=1 < %s +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 %T = type { i32, i32, i32, i32 } @G = constant %T { i32 0, i32 0, i32 17, i32 25 } define internal i32 @test(%T* %p) { -; CHECK-LABEL: define {{[^@]+}}@test -; CHECK-SAME: (i32 [[P_0_2_VAL:%.*]], i32 [[P_0_3_VAL:%.*]]) +; CHECK-LABEL: define {{[^@]+}}@test() ; CHECK-NEXT: entry: -; CHECK-NEXT: [[V:%.*]] = add i32 [[P_0_3_VAL]], [[P_0_2_VAL]] +; CHECK-NEXT: [[A_GEP:%.*]] = getelementptr [[T:%.*]], %T* @G, i64 0, i32 3 +; CHECK-NEXT: [[B_GEP:%.*]] = getelementptr [[T]], %T* @G, i64 0, i32 2 +; CHECK-NEXT: [[A:%.*]] = load i32, i32* [[A_GEP]], align 4 +; CHECK-NEXT: [[B:%.*]] = load i32, i32* [[B_GEP]], align 4 +; CHECK-NEXT: [[V:%.*]] = add i32 [[A]], [[B]] ; CHECK-NEXT: ret i32 [[V]] ; entry: @@ -23,11 +29,7 @@ entry: define i32 @caller() { ; CHECK-LABEL: define {{[^@]+}}@caller() ; CHECK-NEXT: entry: -; CHECK-NEXT: [[G_IDX:%.*]] = getelementptr [[T:%.*]], %T* @G, i64 0, i32 2 -; CHECK-NEXT: [[G_IDX_VAL:%.*]] = load i32, i32* [[G_IDX]] -; CHECK-NEXT: [[G_IDX1:%.*]] = getelementptr [[T]], %T* @G, i64 0, i32 3 -; CHECK-NEXT: [[G_IDX1_VAL:%.*]] = load i32, i32* [[G_IDX1]] -; CHECK-NEXT: [[V:%.*]] = call i32 @test(i32 [[G_IDX_VAL]], i32 [[G_IDX1_VAL]]) +; CHECK-NEXT: [[V:%.*]] = call i32 @test() ; CHECK-NEXT: ret i32 [[V]] ; entry: diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/alignment.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/alignment.ll index 3b0085a019e4..21f7ead3b0a4 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/alignment.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/alignment.ll @@ -1,13 +1,28 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes -; RUN: opt -S -passes='attributor' -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=3 < %s | FileCheck %s +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 define void @f() { -; CHECK-LABEL: define {{[^@]+}}@f() -; CHECK-NEXT: entry: -; CHECK-NEXT: [[A:%.*]] = alloca i32, align 1 -; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[A]], align 1 -; CHECK-NEXT: call void @g(i32 [[TMP0]]) -; CHECK-NEXT: ret void +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@f() +; IS__TUNIT_OPM-NEXT: entry: +; IS__TUNIT_OPM-NEXT: [[A:%.*]] = alloca i32, align 1 +; IS__TUNIT_OPM-NEXT: call void @g(i32* noalias nocapture nonnull readonly dereferenceable(4) [[A]]) +; IS__TUNIT_OPM-NEXT: ret void +; +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@f() +; IS__TUNIT_NPM-NEXT: entry: +; IS__TUNIT_NPM-NEXT: [[A:%.*]] = alloca i32, align 1 +; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[A]], align 1 +; IS__TUNIT_NPM-NEXT: call void @g(i32 [[TMP0]]) +; IS__TUNIT_NPM-NEXT: ret void +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@f() +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: [[A:%.*]] = alloca i32, align 1 +; IS__CGSCC____-NEXT: call void @g(i32* noalias nonnull readonly dereferenceable(4) [[A]]) +; IS__CGSCC____-NEXT: ret void ; entry: %a = alloca i32, align 1 @@ -16,13 +31,25 @@ entry: } define internal void @g(i32* %a) { -; CHECK-LABEL: define {{[^@]+}}@g -; CHECK-SAME: (i32 [[TMP0:%.*]]) -; CHECK-NEXT: [[A_PRIV:%.*]] = alloca i32 -; CHECK-NEXT: store i32 [[TMP0]], i32* [[A_PRIV]] -; CHECK-NEXT: [[AA:%.*]] = load i32, i32* [[A_PRIV]], align 1 -; CHECK-NEXT: call void @z(i32 [[AA]]) -; CHECK-NEXT: ret void +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@g +; IS__TUNIT_OPM-SAME: (i32* noalias nocapture nonnull readonly dereferenceable(4) [[A:%.*]]) +; IS__TUNIT_OPM-NEXT: [[AA:%.*]] = load i32, i32* [[A]], align 1 +; IS__TUNIT_OPM-NEXT: call void @z(i32 [[AA]]) +; IS__TUNIT_OPM-NEXT: ret void +; +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@g +; IS__TUNIT_NPM-SAME: (i32 [[TMP0:%.*]]) +; IS__TUNIT_NPM-NEXT: [[A_PRIV:%.*]] = alloca i32 +; IS__TUNIT_NPM-NEXT: store i32 [[TMP0]], i32* [[A_PRIV]] +; IS__TUNIT_NPM-NEXT: [[AA:%.*]] = load i32, i32* [[A_PRIV]], align 1 +; IS__TUNIT_NPM-NEXT: call void @z(i32 [[AA]]) +; IS__TUNIT_NPM-NEXT: ret void +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@g +; IS__CGSCC____-SAME: (i32* nocapture nonnull readonly dereferenceable(4) [[A:%.*]]) +; IS__CGSCC____-NEXT: [[AA:%.*]] = load i32, i32* [[A]], align 1 +; IS__CGSCC____-NEXT: call void @z(i32 [[AA]]) +; IS__CGSCC____-NEXT: ret void ; %aa = load i32, i32* %a, align 1 call void @z(i32 %aa) diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/attrs.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/attrs.ll index 6e8a2e5e78f5..e28e4e592f12 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/attrs.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/attrs.ll @@ -1,28 +1,75 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=4 < %s | FileCheck %s +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=4 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=4 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 %struct.ss = type { i32, i64 } ; Don't drop 'byval' on %X here. define internal i32 @f(%struct.ss* byval %b, i32* byval %X, i32 %i) nounwind { -; CHECK-LABEL: define {{[^@]+}}@f -; CHECK-SAME: (i32 [[TMP0:%.*]], i64 [[TMP1:%.*]], i32 [[TMP2:%.*]], i32 [[I:%.*]]) -; CHECK-NEXT: entry: -; CHECK-NEXT: [[X_PRIV:%.*]] = alloca i32 -; CHECK-NEXT: store i32 [[TMP2]], i32* [[X_PRIV]] -; CHECK-NEXT: [[B_PRIV:%.*]] = alloca [[STRUCT_SS:%.*]] -; CHECK-NEXT: [[B_PRIV_CAST:%.*]] = bitcast %struct.ss* [[B_PRIV]] to i32* -; CHECK-NEXT: store i32 [[TMP0]], i32* [[B_PRIV_CAST]] -; CHECK-NEXT: [[B_PRIV_0_1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[B_PRIV]], i32 0, i32 1 -; CHECK-NEXT: store i64 [[TMP1]], i64* [[B_PRIV_0_1]] -; CHECK-NEXT: [[TMP:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[B_PRIV]], i32 0, i32 0 -; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 8 -; CHECK-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 1 -; CHECK-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 8 -; CHECK-NEXT: store i32 0, i32* [[X_PRIV]], align 4 -; CHECK-NEXT: [[L:%.*]] = load i32, i32* [[X_PRIV]], align 4 -; CHECK-NEXT: [[A:%.*]] = add i32 [[L]], [[TMP2]] -; CHECK-NEXT: ret i32 [[A]] +; +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@f +; IS__TUNIT_OPM-SAME: (%struct.ss* noalias nocapture nofree nonnull byval align 8 dereferenceable(12) [[B:%.*]], i32* noalias nocapture nofree nonnull byval align 4 dereferenceable(4) [[X:%.*]], i32 [[I:%.*]]) +; IS__TUNIT_OPM-NEXT: entry: +; IS__TUNIT_OPM-NEXT: [[TMP:%.*]] = getelementptr [[STRUCT_SS:%.*]], %struct.ss* [[B]], i32 0, i32 0 +; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 8 +; IS__TUNIT_OPM-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 1 +; IS__TUNIT_OPM-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 8 +; IS__TUNIT_OPM-NEXT: store i32 0, i32* [[X]], align 4 +; IS__TUNIT_OPM-NEXT: [[L:%.*]] = load i32, i32* [[X]], align 4 +; IS__TUNIT_OPM-NEXT: [[A:%.*]] = add i32 [[L]], [[TMP2]] +; IS__TUNIT_OPM-NEXT: ret i32 [[A]] +; +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@f +; IS__TUNIT_NPM-SAME: (i32 [[TMP0:%.*]], i64 [[TMP1:%.*]], i32 [[TMP2:%.*]], i32 [[I:%.*]]) +; IS__TUNIT_NPM-NEXT: entry: +; IS__TUNIT_NPM-NEXT: [[X_PRIV:%.*]] = alloca i32 +; IS__TUNIT_NPM-NEXT: store i32 [[TMP2]], i32* [[X_PRIV]] +; IS__TUNIT_NPM-NEXT: [[B_PRIV:%.*]] = alloca [[STRUCT_SS:%.*]] +; IS__TUNIT_NPM-NEXT: [[B_PRIV_CAST:%.*]] = bitcast %struct.ss* [[B_PRIV]] to i32* +; IS__TUNIT_NPM-NEXT: store i32 [[TMP0]], i32* [[B_PRIV_CAST]] +; IS__TUNIT_NPM-NEXT: [[B_PRIV_0_1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[B_PRIV]], i32 0, i32 1 +; IS__TUNIT_NPM-NEXT: store i64 [[TMP1]], i64* [[B_PRIV_0_1]] +; IS__TUNIT_NPM-NEXT: [[TMP:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[B_PRIV]], i32 0, i32 0 +; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 8 +; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 1 +; IS__TUNIT_NPM-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 8 +; IS__TUNIT_NPM-NEXT: store i32 0, i32* [[X_PRIV]], align 4 +; IS__TUNIT_NPM-NEXT: [[L:%.*]] = load i32, i32* [[X_PRIV]], align 4 +; IS__TUNIT_NPM-NEXT: [[A:%.*]] = add i32 [[L]], [[TMP2]] +; IS__TUNIT_NPM-NEXT: ret i32 [[A]] +; +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f +; IS__CGSCC_OPM-SAME: (%struct.ss* noalias nocapture nofree nonnull byval align 4 dereferenceable(4) [[B:%.*]], i32* noalias nocapture nofree nonnull byval align 4 dereferenceable(4) [[X:%.*]]) +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: [[TMP:%.*]] = getelementptr [[STRUCT_SS:%.*]], %struct.ss* [[B]], i32 0, i32 0 +; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 4 +; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 1 +; IS__CGSCC_OPM-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 4 +; IS__CGSCC_OPM-NEXT: store i32 0, i32* [[X]], align 4 +; IS__CGSCC_OPM-NEXT: [[L:%.*]] = load i32, i32* [[X]], align 4 +; IS__CGSCC_OPM-NEXT: [[A:%.*]] = add i32 [[L]], [[TMP2]] +; IS__CGSCC_OPM-NEXT: ret i32 [[A]] +; +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f +; IS__CGSCC_NPM-SAME: (i32 [[TMP0:%.*]], i64 [[TMP1:%.*]], i32 [[TMP2:%.*]]) +; IS__CGSCC_NPM-NEXT: entry: +; IS__CGSCC_NPM-NEXT: [[X_PRIV:%.*]] = alloca i32 +; IS__CGSCC_NPM-NEXT: store i32 [[TMP2]], i32* [[X_PRIV]] +; IS__CGSCC_NPM-NEXT: [[B_PRIV:%.*]] = alloca [[STRUCT_SS:%.*]] +; IS__CGSCC_NPM-NEXT: [[B_PRIV_CAST:%.*]] = bitcast %struct.ss* [[B_PRIV]] to i32* +; IS__CGSCC_NPM-NEXT: store i32 [[TMP0]], i32* [[B_PRIV_CAST]] +; IS__CGSCC_NPM-NEXT: [[B_PRIV_0_1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[B_PRIV]], i32 0, i32 1 +; IS__CGSCC_NPM-NEXT: store i64 [[TMP1]], i64* [[B_PRIV_0_1]] +; IS__CGSCC_NPM-NEXT: [[TMP:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[B_PRIV]], i32 0, i32 0 +; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 4 +; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 1 +; IS__CGSCC_NPM-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 4 +; IS__CGSCC_NPM-NEXT: store i32 0, i32* [[X_PRIV]], align 4 +; IS__CGSCC_NPM-NEXT: [[L:%.*]] = load i32, i32* [[X_PRIV]], align 4 +; IS__CGSCC_NPM-NEXT: [[A:%.*]] = add i32 [[L]], [[TMP2]] +; IS__CGSCC_NPM-NEXT: ret i32 [[A]] ; entry: @@ -39,21 +86,60 @@ entry: ; Also make sure we don't drop the call zeroext attribute. define i32 @test(i32* %X) { -; CHECK-LABEL: define {{[^@]+}}@test -; CHECK-SAME: (i32* nocapture nofree readonly align 4 [[X:%.*]]) -; CHECK-NEXT: entry: -; CHECK-NEXT: [[S:%.*]] = alloca [[STRUCT_SS:%.*]] -; CHECK-NEXT: [[TMP1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 0 -; CHECK-NEXT: store i32 1, i32* [[TMP1]], align 8 -; CHECK-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1 -; CHECK-NEXT: store i64 2, i64* [[TMP4]], align 4 -; CHECK-NEXT: [[S_CAST:%.*]] = bitcast %struct.ss* [[S]] to i32* -; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[S_CAST]], align 1 -; CHECK-NEXT: [[S_0_1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1 -; CHECK-NEXT: [[TMP1:%.*]] = load i64, i64* [[S_0_1]], align 1 -; CHECK-NEXT: [[TMP2:%.*]] = load i32, i32* [[X]], align 1 -; CHECK-NEXT: [[C:%.*]] = call i32 @f(i32 [[TMP0]], i64 [[TMP1]], i32 [[TMP2]], i32 zeroext 0) -; CHECK-NEXT: ret i32 [[C]] +; +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@test +; IS__TUNIT_OPM-SAME: (i32* nocapture nofree readonly align 4 [[X:%.*]]) +; IS__TUNIT_OPM-NEXT: entry: +; IS__TUNIT_OPM-NEXT: [[S:%.*]] = alloca [[STRUCT_SS:%.*]] +; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 0 +; IS__TUNIT_OPM-NEXT: store i32 1, i32* [[TMP1]], align 8 +; IS__TUNIT_OPM-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1 +; IS__TUNIT_OPM-NEXT: store i64 2, i64* [[TMP4]], align 4 +; IS__TUNIT_OPM-NEXT: [[C:%.*]] = call i32 @f(%struct.ss* noalias nocapture nofree nonnull readonly byval align 8 dereferenceable(12) [[S]], i32* nocapture nofree readonly byval align 4 [[X]], i32 zeroext 0) +; IS__TUNIT_OPM-NEXT: ret i32 [[C]] +; +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@test +; IS__TUNIT_NPM-SAME: (i32* nocapture nofree readonly align 4 [[X:%.*]]) +; IS__TUNIT_NPM-NEXT: entry: +; IS__TUNIT_NPM-NEXT: [[S:%.*]] = alloca [[STRUCT_SS:%.*]] +; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 0 +; IS__TUNIT_NPM-NEXT: store i32 1, i32* [[TMP1]], align 8 +; IS__TUNIT_NPM-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1 +; IS__TUNIT_NPM-NEXT: store i64 2, i64* [[TMP4]], align 4 +; IS__TUNIT_NPM-NEXT: [[S_CAST:%.*]] = bitcast %struct.ss* [[S]] to i32* +; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[S_CAST]], align 1 +; IS__TUNIT_NPM-NEXT: [[S_0_1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1 +; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = load i64, i64* [[S_0_1]], align 1 +; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[X]], align 1 +; IS__TUNIT_NPM-NEXT: [[C:%.*]] = call i32 @f(i32 [[TMP0]], i64 [[TMP1]], i32 [[TMP2]], i32 zeroext 0) +; IS__TUNIT_NPM-NEXT: ret i32 [[C]] +; +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test +; IS__CGSCC_OPM-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(4) [[X:%.*]]) +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: [[S:%.*]] = alloca [[STRUCT_SS:%.*]] +; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 0 +; IS__CGSCC_OPM-NEXT: store i32 1, i32* [[TMP1]], align 8 +; IS__CGSCC_OPM-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1 +; IS__CGSCC_OPM-NEXT: store i64 2, i64* [[TMP4]], align 4 +; IS__CGSCC_OPM-NEXT: [[C:%.*]] = call i32 @f(%struct.ss* noalias nofree nonnull readnone byval align 8 dereferenceable(12) [[S]], i32* noalias nocapture nofree nonnull readnone byval align 4 dereferenceable(4) [[X]]) +; IS__CGSCC_OPM-NEXT: ret i32 [[C]] +; +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test +; IS__CGSCC_NPM-SAME: (i32* nocapture nofree nonnull readonly dereferenceable(4) [[X:%.*]]) +; IS__CGSCC_NPM-NEXT: entry: +; IS__CGSCC_NPM-NEXT: [[S:%.*]] = alloca [[STRUCT_SS:%.*]] +; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 0 +; IS__CGSCC_NPM-NEXT: store i32 1, i32* [[TMP1]], align 8 +; IS__CGSCC_NPM-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1 +; IS__CGSCC_NPM-NEXT: store i64 2, i64* [[TMP4]], align 4 +; IS__CGSCC_NPM-NEXT: [[S_CAST:%.*]] = bitcast %struct.ss* [[S]] to i32* +; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[S_CAST]], align 8 +; IS__CGSCC_NPM-NEXT: [[S_0_1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1 +; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = load i64, i64* [[S_0_1]], align 1 +; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[X]], align 1 +; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call i32 @f(i32 [[TMP0]], i64 [[TMP1]], i32 [[TMP2]]) +; IS__CGSCC_NPM-NEXT: ret i32 [[C]] ; entry: %S = alloca %struct.ss diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/basictest.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/basictest.ll index 7739ad757337..6d2131610fb1 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/basictest.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/basictest.ll @@ -1,18 +1,35 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes -; RUN: opt -S -passes='attributor' -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=7 < %s | FileCheck %s +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=7 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=7 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" define internal i32 @test(i32* %X, i32* %Y) { -; CHECK-LABEL: define {{[^@]+}}@test -; CHECK-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]]) -; CHECK-NEXT: [[Y_PRIV:%.*]] = alloca i32 -; CHECK-NEXT: store i32 [[TMP1]], i32* [[Y_PRIV]] -; CHECK-NEXT: [[X_PRIV:%.*]] = alloca i32 -; CHECK-NEXT: store i32 [[TMP0]], i32* [[X_PRIV]] -; CHECK-NEXT: [[A:%.*]] = load i32, i32* [[X_PRIV]], align 4 -; CHECK-NEXT: [[B:%.*]] = load i32, i32* [[Y_PRIV]], align 4 -; CHECK-NEXT: [[C:%.*]] = add i32 [[A]], [[B]] -; CHECK-NEXT: ret i32 [[C]] +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@test +; IS__TUNIT_OPM-SAME: (i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[X:%.*]], i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[Y:%.*]]) +; IS__TUNIT_OPM-NEXT: [[A:%.*]] = load i32, i32* [[X]], align 4 +; IS__TUNIT_OPM-NEXT: [[B:%.*]] = load i32, i32* [[Y]], align 4 +; IS__TUNIT_OPM-NEXT: [[C:%.*]] = add i32 [[A]], [[B]] +; IS__TUNIT_OPM-NEXT: ret i32 [[C]] +; +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@test +; IS__TUNIT_NPM-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]]) +; IS__TUNIT_NPM-NEXT: [[Y_PRIV:%.*]] = alloca i32 +; IS__TUNIT_NPM-NEXT: store i32 [[TMP1]], i32* [[Y_PRIV]] +; IS__TUNIT_NPM-NEXT: [[X_PRIV:%.*]] = alloca i32 +; IS__TUNIT_NPM-NEXT: store i32 [[TMP0]], i32* [[X_PRIV]] +; IS__TUNIT_NPM-NEXT: [[A:%.*]] = load i32, i32* [[X_PRIV]], align 4 +; IS__TUNIT_NPM-NEXT: [[B:%.*]] = load i32, i32* [[Y_PRIV]], align 4 +; IS__TUNIT_NPM-NEXT: [[C:%.*]] = add i32 [[A]], [[B]] +; IS__TUNIT_NPM-NEXT: ret i32 [[C]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@test +; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[X:%.*]], i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[Y:%.*]]) +; IS__CGSCC____-NEXT: [[A:%.*]] = load i32, i32* [[X]], align 4 +; IS__CGSCC____-NEXT: [[B:%.*]] = load i32, i32* [[Y]], align 4 +; IS__CGSCC____-NEXT: [[C:%.*]] = add i32 [[A]], [[B]] +; IS__CGSCC____-NEXT: ret i32 [[C]] ; %A = load i32, i32* %X %B = load i32, i32* %Y @@ -21,16 +38,30 @@ define internal i32 @test(i32* %X, i32* %Y) { } define internal i32 @caller(i32* %B) { -; CHECK-LABEL: define {{[^@]+}}@caller -; CHECK-SAME: (i32 [[TMP0:%.*]]) -; CHECK-NEXT: [[B_PRIV:%.*]] = alloca i32 -; CHECK-NEXT: store i32 [[TMP0]], i32* [[B_PRIV]] -; CHECK-NEXT: [[A:%.*]] = alloca i32 -; CHECK-NEXT: store i32 1, i32* [[A]], align 4 -; CHECK-NEXT: [[TMP2:%.*]] = load i32, i32* [[A]], align 1 -; CHECK-NEXT: [[TMP3:%.*]] = load i32, i32* [[B_PRIV]], align 1 -; CHECK-NEXT: [[C:%.*]] = call i32 @test(i32 [[TMP2]], i32 [[TMP3]]) -; CHECK-NEXT: ret i32 [[C]] +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@caller +; IS__TUNIT_OPM-SAME: (i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B:%.*]]) +; IS__TUNIT_OPM-NEXT: [[A:%.*]] = alloca i32 +; IS__TUNIT_OPM-NEXT: store i32 1, i32* [[A]], align 4 +; IS__TUNIT_OPM-NEXT: [[C:%.*]] = call i32 @test(i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A]], i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B]]) +; IS__TUNIT_OPM-NEXT: ret i32 [[C]] +; +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@caller +; IS__TUNIT_NPM-SAME: (i32 [[TMP0:%.*]]) +; IS__TUNIT_NPM-NEXT: [[B_PRIV:%.*]] = alloca i32 +; IS__TUNIT_NPM-NEXT: store i32 [[TMP0]], i32* [[B_PRIV]] +; IS__TUNIT_NPM-NEXT: [[A:%.*]] = alloca i32 +; IS__TUNIT_NPM-NEXT: store i32 1, i32* [[A]], align 4 +; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[A]], align 1 +; IS__TUNIT_NPM-NEXT: [[TMP3:%.*]] = load i32, i32* [[B_PRIV]], align 1 +; IS__TUNIT_NPM-NEXT: [[C:%.*]] = call i32 @test(i32 [[TMP2]], i32 [[TMP3]]) +; IS__TUNIT_NPM-NEXT: ret i32 [[C]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@caller +; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B:%.*]]) +; IS__CGSCC____-NEXT: [[A:%.*]] = alloca i32 +; IS__CGSCC____-NEXT: store i32 1, i32* [[A]], align 4 +; IS__CGSCC____-NEXT: [[C:%.*]] = call i32 @test(i32* noalias nofree nonnull readonly align 4 dereferenceable(4) [[A]], i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B]]) +; IS__CGSCC____-NEXT: ret i32 [[C]] ; %A = alloca i32 store i32 1, i32* %A @@ -39,12 +70,24 @@ define internal i32 @caller(i32* %B) { } define i32 @callercaller() { -; CHECK-LABEL: define {{[^@]+}}@callercaller() -; CHECK-NEXT: [[B:%.*]] = alloca i32 -; CHECK-NEXT: store i32 2, i32* [[B]], align 4 -; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[B]], align 1 -; CHECK-NEXT: [[X:%.*]] = call i32 @caller(i32 [[TMP1]]) -; CHECK-NEXT: ret i32 [[X]] +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@callercaller() +; IS__TUNIT_OPM-NEXT: [[B:%.*]] = alloca i32 +; IS__TUNIT_OPM-NEXT: store i32 2, i32* [[B]], align 4 +; IS__TUNIT_OPM-NEXT: [[X:%.*]] = call i32 @caller(i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B]]) +; IS__TUNIT_OPM-NEXT: ret i32 [[X]] +; +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@callercaller() +; IS__TUNIT_NPM-NEXT: [[B:%.*]] = alloca i32 +; IS__TUNIT_NPM-NEXT: store i32 2, i32* [[B]], align 4 +; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[B]], align 1 +; IS__TUNIT_NPM-NEXT: [[X:%.*]] = call i32 @caller(i32 [[TMP1]]) +; IS__TUNIT_NPM-NEXT: ret i32 [[X]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@callercaller() +; IS__CGSCC____-NEXT: [[B:%.*]] = alloca i32 +; IS__CGSCC____-NEXT: store i32 2, i32* [[B]], align 4 +; IS__CGSCC____-NEXT: [[X:%.*]] = call i32 @caller(i32* noalias nofree nonnull readonly align 4 dereferenceable(4) [[B]]) +; IS__CGSCC____-NEXT: ret i32 [[X]] ; %B = alloca i32 store i32 2, i32* %B diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/byval-2.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/byval-2.ll index 6fdfb47a825d..f867c3c36ebd 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/byval-2.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/byval-2.ll @@ -1,9 +1,39 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=3 < %s | FileCheck %s +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 %struct.ss = type { i32, i64 } define internal void @f(%struct.ss* byval %b, i32* byval %X) nounwind { +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f +; IS__CGSCC_OPM-SAME: (%struct.ss* noalias nocapture nofree nonnull byval align 4 dereferenceable(4) [[B:%.*]], i32* noalias nocapture nofree nonnull writeonly byval align 4 dereferenceable(4) [[X:%.*]]) +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: [[TMP:%.*]] = getelementptr [[STRUCT_SS:%.*]], %struct.ss* [[B]], i32 0, i32 0 +; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 4 +; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 1 +; IS__CGSCC_OPM-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 4 +; IS__CGSCC_OPM-NEXT: store i32 0, i32* [[X]], align 4 +; IS__CGSCC_OPM-NEXT: ret void +; +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f +; IS__CGSCC_NPM-SAME: (i32 [[TMP0:%.*]], i64 [[TMP1:%.*]], i32 [[TMP2:%.*]]) +; IS__CGSCC_NPM-NEXT: entry: +; IS__CGSCC_NPM-NEXT: [[X_PRIV:%.*]] = alloca i32 +; IS__CGSCC_NPM-NEXT: store i32 [[TMP2]], i32* [[X_PRIV]] +; IS__CGSCC_NPM-NEXT: [[B_PRIV:%.*]] = alloca [[STRUCT_SS:%.*]] +; IS__CGSCC_NPM-NEXT: [[B_PRIV_CAST:%.*]] = bitcast %struct.ss* [[B_PRIV]] to i32* +; IS__CGSCC_NPM-NEXT: store i32 [[TMP0]], i32* [[B_PRIV_CAST]] +; IS__CGSCC_NPM-NEXT: [[B_PRIV_0_1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[B_PRIV]], i32 0, i32 1 +; IS__CGSCC_NPM-NEXT: store i64 [[TMP1]], i64* [[B_PRIV_0_1]] +; IS__CGSCC_NPM-NEXT: [[TMP:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[B_PRIV]], i32 0, i32 0 +; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 4 +; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 1 +; IS__CGSCC_NPM-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 4 +; IS__CGSCC_NPM-NEXT: store i32 0, i32* [[X_PRIV]], align 4 +; IS__CGSCC_NPM-NEXT: ret void +; entry: %tmp = getelementptr %struct.ss, %struct.ss* %b, i32 0, i32 0 %tmp1 = load i32, i32* %tmp, align 4 @@ -15,15 +45,36 @@ entry: } define i32 @test(i32* %X) { -; CHECK-LABEL: define {{[^@]+}}@test -; CHECK-SAME: (i32* nocapture nofree readonly align 4 [[X:%.*]]) -; CHECK-NEXT: entry: -; CHECK-NEXT: [[S:%.*]] = alloca [[STRUCT_SS:%.*]] -; CHECK-NEXT: [[TMP1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 0 -; CHECK-NEXT: store i32 1, i32* [[TMP1]], align 8 -; CHECK-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1 -; CHECK-NEXT: store i64 2, i64* [[TMP4]], align 4 -; CHECK-NEXT: ret i32 0 +; +; IS__TUNIT____-LABEL: define {{[^@]+}}@test +; IS__TUNIT____-SAME: (i32* nocapture nofree readonly align 4 [[X:%.*]]) +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: [[S:%.*]] = alloca [[STRUCT_SS:%.*]] +; IS__TUNIT____-NEXT: [[TMP1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 0 +; IS__TUNIT____-NEXT: store i32 1, i32* [[TMP1]], align 8 +; IS__TUNIT____-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1 +; IS__TUNIT____-NEXT: store i64 2, i64* [[TMP4]], align 4 +; IS__TUNIT____-NEXT: ret i32 0 +; +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test +; IS__CGSCC_OPM-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(4) [[X:%.*]]) +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: [[S:%.*]] = alloca [[STRUCT_SS:%.*]] +; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 0 +; IS__CGSCC_OPM-NEXT: store i32 1, i32* [[TMP1]], align 8 +; IS__CGSCC_OPM-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1 +; IS__CGSCC_OPM-NEXT: store i64 2, i64* [[TMP4]], align 4 +; IS__CGSCC_OPM-NEXT: ret i32 0 +; +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test +; IS__CGSCC_NPM-SAME: (i32* nocapture nofree nonnull readonly dereferenceable(4) [[X:%.*]]) +; IS__CGSCC_NPM-NEXT: entry: +; IS__CGSCC_NPM-NEXT: [[S:%.*]] = alloca [[STRUCT_SS:%.*]] +; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 0 +; IS__CGSCC_NPM-NEXT: store i32 1, i32* [[TMP1]], align 8 +; IS__CGSCC_NPM-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1 +; IS__CGSCC_NPM-NEXT: store i64 2, i64* [[TMP4]], align 4 +; IS__CGSCC_NPM-NEXT: ret i32 0 ; entry: %S = alloca %struct.ss diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/byval.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/byval.ll index 545cbc0da701..c8d1afef5709 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/byval.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/byval.ll @@ -1,24 +1,59 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes -; RUN: opt -S -passes='attributor' -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=2 < %s | FileCheck %s +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" %struct.ss = type { i32, i64 } define internal i32 @f(%struct.ss* byval %b) nounwind { -; CHECK-LABEL: define {{[^@]+}}@f -; CHECK-SAME: (i32 [[TMP0:%.*]], i64 [[TMP1:%.*]]) -; CHECK-NEXT: entry: -; CHECK-NEXT: [[B_PRIV:%.*]] = alloca [[STRUCT_SS:%.*]] -; CHECK-NEXT: [[B_PRIV_CAST:%.*]] = bitcast %struct.ss* [[B_PRIV]] to i32* -; CHECK-NEXT: store i32 [[TMP0]], i32* [[B_PRIV_CAST]] -; CHECK-NEXT: [[B_PRIV_0_1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[B_PRIV]], i32 0, i32 1 -; CHECK-NEXT: store i64 [[TMP1]], i64* [[B_PRIV_0_1]] -; CHECK-NEXT: [[TMP:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[B_PRIV]], i32 0, i32 0 -; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 8 -; CHECK-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 1 -; CHECK-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 8 -; CHECK-NEXT: ret i32 [[TMP1]] +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@f +; IS__TUNIT_OPM-SAME: (%struct.ss* noalias nocapture nofree nonnull byval align 8 dereferenceable(12) [[B:%.*]]) +; IS__TUNIT_OPM-NEXT: entry: +; IS__TUNIT_OPM-NEXT: [[TMP:%.*]] = getelementptr [[STRUCT_SS:%.*]], %struct.ss* [[B]], i32 0, i32 0 +; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 8 +; IS__TUNIT_OPM-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 1 +; IS__TUNIT_OPM-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 8 +; IS__TUNIT_OPM-NEXT: ret i32 [[TMP1]] +; +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@f +; IS__TUNIT_NPM-SAME: (i32 [[TMP0:%.*]], i64 [[TMP1:%.*]]) +; IS__TUNIT_NPM-NEXT: entry: +; IS__TUNIT_NPM-NEXT: [[B_PRIV:%.*]] = alloca [[STRUCT_SS:%.*]] +; IS__TUNIT_NPM-NEXT: [[B_PRIV_CAST:%.*]] = bitcast %struct.ss* [[B_PRIV]] to i32* +; IS__TUNIT_NPM-NEXT: store i32 [[TMP0]], i32* [[B_PRIV_CAST]] +; IS__TUNIT_NPM-NEXT: [[B_PRIV_0_1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[B_PRIV]], i32 0, i32 1 +; IS__TUNIT_NPM-NEXT: store i64 [[TMP1]], i64* [[B_PRIV_0_1]] +; IS__TUNIT_NPM-NEXT: [[TMP:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[B_PRIV]], i32 0, i32 0 +; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 8 +; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 1 +; IS__TUNIT_NPM-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 8 +; IS__TUNIT_NPM-NEXT: ret i32 [[TMP1]] +; +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f +; IS__CGSCC_OPM-SAME: (%struct.ss* noalias nocapture nofree nonnull byval align 4 dereferenceable(4) [[B:%.*]]) +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: [[TMP:%.*]] = getelementptr [[STRUCT_SS:%.*]], %struct.ss* [[B]], i32 0, i32 0 +; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 4 +; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 1 +; IS__CGSCC_OPM-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 4 +; IS__CGSCC_OPM-NEXT: ret i32 [[TMP1]] +; +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f +; IS__CGSCC_NPM-SAME: (i32 [[TMP0:%.*]], i64 [[TMP1:%.*]]) +; IS__CGSCC_NPM-NEXT: entry: +; IS__CGSCC_NPM-NEXT: [[B_PRIV:%.*]] = alloca [[STRUCT_SS:%.*]] +; IS__CGSCC_NPM-NEXT: [[B_PRIV_CAST:%.*]] = bitcast %struct.ss* [[B_PRIV]] to i32* +; IS__CGSCC_NPM-NEXT: store i32 [[TMP0]], i32* [[B_PRIV_CAST]] +; IS__CGSCC_NPM-NEXT: [[B_PRIV_0_1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[B_PRIV]], i32 0, i32 1 +; IS__CGSCC_NPM-NEXT: store i64 [[TMP1]], i64* [[B_PRIV_0_1]] +; IS__CGSCC_NPM-NEXT: [[TMP:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[B_PRIV]], i32 0, i32 0 +; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 4 +; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 1 +; IS__CGSCC_NPM-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 4 +; IS__CGSCC_NPM-NEXT: ret i32 [[TMP1]] ; entry: %tmp = getelementptr %struct.ss, %struct.ss* %b, i32 0, i32 0 @@ -30,19 +65,37 @@ entry: define internal i32 @g(%struct.ss* byval align 32 %b) nounwind { -; CHECK-LABEL: define {{[^@]+}}@g -; CHECK-SAME: (i32 [[TMP0:%.*]], i64 [[TMP1:%.*]]) -; CHECK-NEXT: entry: -; CHECK-NEXT: [[B_PRIV:%.*]] = alloca [[STRUCT_SS:%.*]] -; CHECK-NEXT: [[B_PRIV_CAST:%.*]] = bitcast %struct.ss* [[B_PRIV]] to i32* -; CHECK-NEXT: store i32 [[TMP0]], i32* [[B_PRIV_CAST]] -; CHECK-NEXT: [[B_PRIV_0_1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[B_PRIV]], i32 0, i32 1 -; CHECK-NEXT: store i64 [[TMP1]], i64* [[B_PRIV_0_1]] -; CHECK-NEXT: [[TMP:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[B_PRIV]], i32 0, i32 0 -; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 32 -; CHECK-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 1 -; CHECK-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 32 -; CHECK-NEXT: ret i32 [[TMP2]] +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@g +; IS__TUNIT_OPM-SAME: (%struct.ss* noalias nocapture nofree nonnull byval align 32 dereferenceable(12) [[B:%.*]]) +; IS__TUNIT_OPM-NEXT: entry: +; IS__TUNIT_OPM-NEXT: [[TMP:%.*]] = getelementptr [[STRUCT_SS:%.*]], %struct.ss* [[B]], i32 0, i32 0 +; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 32 +; IS__TUNIT_OPM-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 1 +; IS__TUNIT_OPM-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 32 +; IS__TUNIT_OPM-NEXT: ret i32 [[TMP2]] +; +; IS________NPM-LABEL: define {{[^@]+}}@g +; IS________NPM-SAME: (i32 [[TMP0:%.*]], i64 [[TMP1:%.*]]) +; IS________NPM-NEXT: entry: +; IS________NPM-NEXT: [[B_PRIV:%.*]] = alloca [[STRUCT_SS:%.*]] +; IS________NPM-NEXT: [[B_PRIV_CAST:%.*]] = bitcast %struct.ss* [[B_PRIV]] to i32* +; IS________NPM-NEXT: store i32 [[TMP0]], i32* [[B_PRIV_CAST]] +; IS________NPM-NEXT: [[B_PRIV_0_1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[B_PRIV]], i32 0, i32 1 +; IS________NPM-NEXT: store i64 [[TMP1]], i64* [[B_PRIV_0_1]] +; IS________NPM-NEXT: [[TMP:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[B_PRIV]], i32 0, i32 0 +; IS________NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 32 +; IS________NPM-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 1 +; IS________NPM-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 32 +; IS________NPM-NEXT: ret i32 [[TMP2]] +; +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@g +; IS__CGSCC_OPM-SAME: (%struct.ss* noalias nocapture nofree nonnull byval align 32 dereferenceable(4) [[B:%.*]]) +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: [[TMP:%.*]] = getelementptr [[STRUCT_SS:%.*]], %struct.ss* [[B]], i32 0, i32 0 +; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 32 +; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 1 +; IS__CGSCC_OPM-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 32 +; IS__CGSCC_OPM-NEXT: ret i32 [[TMP2]] ; entry: %tmp = getelementptr %struct.ss, %struct.ss* %b, i32 0, i32 0 @@ -54,25 +107,69 @@ entry: define i32 @main() nounwind { -; CHECK-LABEL: define {{[^@]+}}@main() -; CHECK-NEXT: entry: -; CHECK-NEXT: [[S:%.*]] = alloca [[STRUCT_SS:%.*]] -; CHECK-NEXT: [[TMP1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 0 -; CHECK-NEXT: store i32 1, i32* [[TMP1]], align 8 -; CHECK-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1 -; CHECK-NEXT: store i64 2, i64* [[TMP4]], align 4 -; CHECK-NEXT: [[S_CAST:%.*]] = bitcast %struct.ss* [[S]] to i32* -; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[S_CAST]], align 1 -; CHECK-NEXT: [[S_0_1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1 -; CHECK-NEXT: [[TMP1:%.*]] = load i64, i64* [[S_0_1]], align 1 -; CHECK-NEXT: [[C0:%.*]] = call i32 @f(i32 [[TMP0]], i64 [[TMP1]]) -; CHECK-NEXT: [[S_CAST1:%.*]] = bitcast %struct.ss* [[S]] to i32* -; CHECK-NEXT: [[TMP2:%.*]] = load i32, i32* [[S_CAST1]], align 1 -; CHECK-NEXT: [[S_0_12:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1 -; CHECK-NEXT: [[TMP3:%.*]] = load i64, i64* [[S_0_12]], align 1 -; CHECK-NEXT: [[C1:%.*]] = call i32 @g(i32 [[TMP2]], i64 [[TMP3]]) -; CHECK-NEXT: [[A:%.*]] = add i32 [[C0]], [[C1]] -; CHECK-NEXT: ret i32 [[A]] +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@main() +; IS__TUNIT_OPM-NEXT: entry: +; IS__TUNIT_OPM-NEXT: [[S:%.*]] = alloca [[STRUCT_SS:%.*]] +; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 0 +; IS__TUNIT_OPM-NEXT: store i32 1, i32* [[TMP1]], align 8 +; IS__TUNIT_OPM-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1 +; IS__TUNIT_OPM-NEXT: store i64 2, i64* [[TMP4]], align 4 +; IS__TUNIT_OPM-NEXT: [[C0:%.*]] = call i32 @f(%struct.ss* noalias nocapture nofree nonnull readonly byval align 8 dereferenceable(12) [[S]]) +; IS__TUNIT_OPM-NEXT: [[C1:%.*]] = call i32 @g(%struct.ss* noalias nocapture nofree nonnull readonly byval align 32 dereferenceable(12) [[S]]) +; IS__TUNIT_OPM-NEXT: [[A:%.*]] = add i32 [[C0]], [[C1]] +; IS__TUNIT_OPM-NEXT: ret i32 [[A]] +; +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@main() +; IS__TUNIT_NPM-NEXT: entry: +; IS__TUNIT_NPM-NEXT: [[S:%.*]] = alloca [[STRUCT_SS:%.*]] +; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 0 +; IS__TUNIT_NPM-NEXT: store i32 1, i32* [[TMP1]], align 8 +; IS__TUNIT_NPM-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1 +; IS__TUNIT_NPM-NEXT: store i64 2, i64* [[TMP4]], align 4 +; IS__TUNIT_NPM-NEXT: [[S_CAST:%.*]] = bitcast %struct.ss* [[S]] to i32* +; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[S_CAST]], align 1 +; IS__TUNIT_NPM-NEXT: [[S_0_1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1 +; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = load i64, i64* [[S_0_1]], align 1 +; IS__TUNIT_NPM-NEXT: [[C0:%.*]] = call i32 @f(i32 [[TMP0]], i64 [[TMP1]]) +; IS__TUNIT_NPM-NEXT: [[S_CAST1:%.*]] = bitcast %struct.ss* [[S]] to i32* +; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[S_CAST1]], align 1 +; IS__TUNIT_NPM-NEXT: [[S_0_12:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1 +; IS__TUNIT_NPM-NEXT: [[TMP3:%.*]] = load i64, i64* [[S_0_12]], align 1 +; IS__TUNIT_NPM-NEXT: [[C1:%.*]] = call i32 @g(i32 [[TMP2]], i64 [[TMP3]]) +; IS__TUNIT_NPM-NEXT: [[A:%.*]] = add i32 [[C0]], [[C1]] +; IS__TUNIT_NPM-NEXT: ret i32 [[A]] +; +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@main() +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: [[S:%.*]] = alloca [[STRUCT_SS:%.*]] +; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 0 +; IS__CGSCC_OPM-NEXT: store i32 1, i32* [[TMP1]], align 32 +; IS__CGSCC_OPM-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1 +; IS__CGSCC_OPM-NEXT: store i64 2, i64* [[TMP4]], align 4 +; IS__CGSCC_OPM-NEXT: [[C0:%.*]] = call i32 @f(%struct.ss* noalias nofree nonnull readnone byval align 32 dereferenceable(12) [[S]]) +; IS__CGSCC_OPM-NEXT: [[C1:%.*]] = call i32 @g(%struct.ss* noalias nofree nonnull readnone byval align 32 dereferenceable(12) [[S]]) +; IS__CGSCC_OPM-NEXT: [[A:%.*]] = add i32 [[C0]], [[C1]] +; IS__CGSCC_OPM-NEXT: ret i32 [[A]] +; +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@main() +; IS__CGSCC_NPM-NEXT: entry: +; IS__CGSCC_NPM-NEXT: [[S:%.*]] = alloca [[STRUCT_SS:%.*]] +; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 0 +; IS__CGSCC_NPM-NEXT: store i32 1, i32* [[TMP1]], align 8 +; IS__CGSCC_NPM-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1 +; IS__CGSCC_NPM-NEXT: store i64 2, i64* [[TMP4]], align 4 +; IS__CGSCC_NPM-NEXT: [[S_CAST:%.*]] = bitcast %struct.ss* [[S]] to i32* +; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[S_CAST]], align 8 +; IS__CGSCC_NPM-NEXT: [[S_0_1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1 +; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = load i64, i64* [[S_0_1]], align 1 +; IS__CGSCC_NPM-NEXT: [[C0:%.*]] = call i32 @f(i32 [[TMP0]], i64 [[TMP1]]) +; IS__CGSCC_NPM-NEXT: [[S_CAST1:%.*]] = bitcast %struct.ss* [[S]] to i32* +; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[S_CAST1]], align 8 +; IS__CGSCC_NPM-NEXT: [[S_0_12:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1 +; IS__CGSCC_NPM-NEXT: [[TMP3:%.*]] = load i64, i64* [[S_0_12]], align 1 +; IS__CGSCC_NPM-NEXT: [[C1:%.*]] = call i32 @g(i32 [[TMP2]], i64 [[TMP3]]) +; IS__CGSCC_NPM-NEXT: [[A:%.*]] = add i32 [[C0]], [[C1]] +; IS__CGSCC_NPM-NEXT: ret i32 [[A]] ; entry: %S = alloca %struct.ss diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/chained.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/chained.ll index 6e9f98007e46..5684807e4745 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/chained.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/chained.ll @@ -1,10 +1,14 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes -; RUN: opt -S -passes='attributor' -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=1 < %s | FileCheck %s +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 @G1 = constant i32 0 @G2 = constant i32* @G1 define internal i32 @test(i32** %x) { +; ; CHECK-LABEL: define {{[^@]+}}@test() ; CHECK-NEXT: entry: ; CHECK-NEXT: [[Y:%.*]] = load i32*, i32** @G2, align 8 diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/control-flow.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/control-flow.ll index 494107d17d8b..142df98051eb 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/control-flow.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/control-flow.ll @@ -1,5 +1,8 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes -; RUN: opt -S -passes='attributor' -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=3 < %s | FileCheck %s +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 ; Don't promote around control flow. define internal i32 @callee(i1 %C, i32* %P) { diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/control-flow2.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/control-flow2.ll index 5636a0a0e97d..773df89affb5 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/control-flow2.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/control-flow2.ll @@ -1,19 +1,40 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes -; RUN: opt -S -passes='attributor' -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=7 < %s | FileCheck %s +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=7 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=7 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" define internal i32 @callee(i1 %C, i32* %P) { -; CHECK-LABEL: define {{[^@]+}}@callee -; CHECK-SAME: (i1 [[C:%.*]], i32 [[TMP0:%.*]]) -; CHECK-NEXT: [[P_PRIV:%.*]] = alloca i32 -; CHECK-NEXT: store i32 [[TMP0]], i32* [[P_PRIV]] -; CHECK-NEXT: br label [[F:%.*]] -; CHECK: T: -; CHECK-NEXT: unreachable -; CHECK: F: -; CHECK-NEXT: [[X:%.*]] = load i32, i32* [[P_PRIV]], align 4 -; CHECK-NEXT: ret i32 [[X]] +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@callee +; IS__TUNIT_OPM-SAME: (i1 [[C:%.*]], i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P:%.*]]) +; IS__TUNIT_OPM-NEXT: br label [[F:%.*]] +; IS__TUNIT_OPM: T: +; IS__TUNIT_OPM-NEXT: unreachable +; IS__TUNIT_OPM: F: +; IS__TUNIT_OPM-NEXT: [[X:%.*]] = load i32, i32* [[P]], align 4 +; IS__TUNIT_OPM-NEXT: ret i32 [[X]] +; +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@callee +; IS__TUNIT_NPM-SAME: (i1 [[C:%.*]], i32 [[TMP0:%.*]]) +; IS__TUNIT_NPM-NEXT: [[P_PRIV:%.*]] = alloca i32 +; IS__TUNIT_NPM-NEXT: store i32 [[TMP0]], i32* [[P_PRIV]] +; IS__TUNIT_NPM-NEXT: br label [[F:%.*]] +; IS__TUNIT_NPM: T: +; IS__TUNIT_NPM-NEXT: unreachable +; IS__TUNIT_NPM: F: +; IS__TUNIT_NPM-NEXT: [[X:%.*]] = load i32, i32* [[P_PRIV]], align 4 +; IS__TUNIT_NPM-NEXT: ret i32 [[X]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@callee +; IS__CGSCC____-SAME: (i32* nocapture nofree readonly [[P:%.*]]) +; IS__CGSCC____-NEXT: br label [[F:%.*]] +; IS__CGSCC____: T: +; IS__CGSCC____-NEXT: unreachable +; IS__CGSCC____: F: +; IS__CGSCC____-NEXT: [[X:%.*]] = load i32, i32* [[P]] +; IS__CGSCC____-NEXT: ret i32 [[X]] ; br i1 %C, label %T, label %F @@ -26,12 +47,24 @@ F: ; preds = %0 } define i32 @foo() { -; CHECK-LABEL: define {{[^@]+}}@foo() -; CHECK-NEXT: [[A:%.*]] = alloca i32 -; CHECK-NEXT: store i32 17, i32* [[A]], align 4 -; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[A]], align 1 -; CHECK-NEXT: [[X:%.*]] = call i32 @callee(i1 false, i32 [[TMP1]]) -; CHECK-NEXT: ret i32 [[X]] +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@foo() +; IS__TUNIT_OPM-NEXT: [[A:%.*]] = alloca i32 +; IS__TUNIT_OPM-NEXT: store i32 17, i32* [[A]], align 4 +; IS__TUNIT_OPM-NEXT: [[X:%.*]] = call i32 @callee(i1 false, i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A]]) +; IS__TUNIT_OPM-NEXT: ret i32 [[X]] +; +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@foo() +; IS__TUNIT_NPM-NEXT: [[A:%.*]] = alloca i32 +; IS__TUNIT_NPM-NEXT: store i32 17, i32* [[A]], align 4 +; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[A]], align 1 +; IS__TUNIT_NPM-NEXT: [[X:%.*]] = call i32 @callee(i1 false, i32 [[TMP1]]) +; IS__TUNIT_NPM-NEXT: ret i32 [[X]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@foo() +; IS__CGSCC____-NEXT: [[A:%.*]] = alloca i32 +; IS__CGSCC____-NEXT: store i32 17, i32* [[A]], align 4 +; IS__CGSCC____-NEXT: [[X:%.*]] = call i32 @callee(i32* noalias nofree nonnull readonly align 4 dereferenceable(4) [[A]]) +; IS__CGSCC____-NEXT: ret i32 [[X]] ; %A = alloca i32 ; [#uses=2] store i32 17, i32* %A diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/crash.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/crash.ll index db3db632e5f2..9d7fd443fe29 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/crash.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/crash.ll @@ -1,30 +1,22 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes -; RUN: opt -S -passes='attributor' -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=3 < %s | FileCheck %s --check-prefixes=CHECK,ATTRIBUTOR -; RUN: opt -S -passes='cgscc(inline),attributor' -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=3 < %s | FileCheck %s --check-prefixes=CHECK,INLINE_ATTRIBUTOR +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 %S = type { %S* } ; Inlining should nuke the invoke (and any inlined calls) here even with ; argument promotion running along with it. define void @zot() personality i32 (...)* @wibble { -; ATTRIBUTOR-LABEL: define {{[^@]+}}@zot() #0 personality i32 (...)* @wibble -; ATTRIBUTOR-NEXT: bb: -; ATTRIBUTOR-NEXT: call void @hoge() -; ATTRIBUTOR-NEXT: unreachable -; ATTRIBUTOR: bb1: -; ATTRIBUTOR-NEXT: unreachable -; ATTRIBUTOR: bb2: -; ATTRIBUTOR-NEXT: unreachable -; -; INLINE_ATTRIBUTOR-LABEL: define {{[^@]+}}@zot() #0 personality i32 (...)* @wibble -; INLINE_ATTRIBUTOR-NEXT: bb: -; INLINE_ATTRIBUTOR-NEXT: unreachable -; INLINE_ATTRIBUTOR: hoge.exit: -; INLINE_ATTRIBUTOR-NEXT: unreachable -; INLINE_ATTRIBUTOR: bb1: -; INLINE_ATTRIBUTOR-NEXT: unreachable -; INLINE_ATTRIBUTOR: bb2: -; INLINE_ATTRIBUTOR-NEXT: unreachable +; CHECK-LABEL: define {{[^@]+}}@zot() #0 personality i32 (...)* @wibble +; CHECK-NEXT: bb: +; CHECK-NEXT: call void @hoge() +; CHECK-NEXT: unreachable +; CHECK: bb1: +; CHECK-NEXT: unreachable +; CHECK: bb2: +; CHECK-NEXT: unreachable ; bb: invoke void @hoge() @@ -40,9 +32,9 @@ bb2: } define internal void @hoge() { -; ATTRIBUTOR-LABEL: define {{[^@]+}}@hoge() -; ATTRIBUTOR-NEXT: bb: -; ATTRIBUTOR-NEXT: unreachable +; CHECK-LABEL: define {{[^@]+}}@hoge() +; CHECK-NEXT: bb: +; CHECK-NEXT: unreachable ; bb: %tmp = call fastcc i8* @spam(i1 (i8*)* @eggs) @@ -51,6 +43,10 @@ bb: } define internal fastcc i8* @spam(i1 (i8*)* %arg) { +; IS__CGSCC____-LABEL: define {{[^@]+}}@spam() +; IS__CGSCC____-NEXT: bb: +; IS__CGSCC____-NEXT: unreachable +; bb: unreachable } @@ -62,15 +58,26 @@ bb: } define internal i1 @barney(i8* %arg) { +; IS__CGSCC____-LABEL: define {{[^@]+}}@barney() +; IS__CGSCC____-NEXT: bb: +; IS__CGSCC____-NEXT: ret i1 undef +; bb: ret i1 undef } define i32 @test_inf_promote_caller(i32 %arg) { -; CHECK-LABEL: define {{[^@]+}}@test_inf_promote_caller -; CHECK-SAME: (i32 [[ARG:%.*]]) -; CHECK-NEXT: bb: -; CHECK-NEXT: unreachable +; IS__TUNIT____-LABEL: define {{[^@]+}}@test_inf_promote_caller +; IS__TUNIT____-SAME: (i32 [[ARG:%.*]]) +; IS__TUNIT____-NEXT: bb: +; IS__TUNIT____-NEXT: unreachable +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@test_inf_promote_caller +; IS__CGSCC____-SAME: (i32 [[ARG:%.*]]) +; IS__CGSCC____-NEXT: bb: +; IS__CGSCC____-NEXT: [[TMP:%.*]] = alloca [[S:%.*]] +; IS__CGSCC____-NEXT: [[TMP1:%.*]] = alloca [[S]] +; IS__CGSCC____-NEXT: unreachable ; bb: %tmp = alloca %S @@ -81,6 +88,10 @@ bb: } define internal i32 @test_inf_promote_callee(%S* %arg, %S* %arg1) { +; IS__CGSCC____-LABEL: define {{[^@]+}}@test_inf_promote_callee() +; IS__CGSCC____-NEXT: bb: +; IS__CGSCC____-NEXT: unreachable +; bb: %tmp = getelementptr %S, %S* %arg1, i32 0, i32 0 %tmp2 = load %S*, %S** %tmp diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/dbg.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/dbg.ll index 43ee9dd13d8d..8a02146d893b 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/dbg.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/dbg.ll @@ -1,5 +1,8 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=2 < %s | FileCheck %s +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 declare void @sink(i32) @@ -29,11 +32,17 @@ define internal void @test_byval(%struct.pair* byval %P) { } define void @caller(i32** %Y, %struct.pair* %P) { -; CHECK-LABEL: define {{[^@]+}}@caller -; CHECK-SAME: (i32** nocapture readonly [[Y:%.*]], %struct.pair* nocapture nofree readnone [[P:%.*]]) -; CHECK-NEXT: call void @test(i32** nocapture readonly align 8 [[Y]]), !dbg !4 -; CHECK-NEXT: call void @test_byval(), !dbg !5 -; CHECK-NEXT: ret void +; IS__TUNIT____-LABEL: define {{[^@]+}}@caller +; IS__TUNIT____-SAME: (i32** nocapture readonly [[Y:%.*]], %struct.pair* nocapture nofree readnone [[P:%.*]]) +; IS__TUNIT____-NEXT: call void @test(i32** nocapture readonly align 8 [[Y]]), !dbg !4 +; IS__TUNIT____-NEXT: call void @test_byval(), !dbg !5 +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@caller +; IS__CGSCC____-SAME: (i32** nocapture nonnull readonly align 8 dereferenceable(8) [[Y:%.*]], %struct.pair* nocapture nofree readnone [[P:%.*]]) +; IS__CGSCC____-NEXT: call void @test(i32** nocapture nonnull readonly align 8 dereferenceable(8) [[Y]]), !dbg !4 +; IS__CGSCC____-NEXT: call void @test_byval(), !dbg !5 +; IS__CGSCC____-NEXT: ret void ; call void @test(i32** %Y), !dbg !1 diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/fp80.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/fp80.ll index b9ee30fac9b9..75935664999e 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/fp80.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/fp80.ll @@ -1,5 +1,8 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=3 < %s | FileCheck %s +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" @@ -26,6 +29,10 @@ entry: } define internal i8 @UseLongDoubleUnsafely(%union.u* byval align 16 %arg) { +; IS__CGSCC____-LABEL: define {{[^@]+}}@UseLongDoubleUnsafely() +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: ret i8 undef +; entry: %bitcast = bitcast %union.u* %arg to %struct.s* %gep = getelementptr inbounds %struct.s, %struct.s* %bitcast, i64 0, i32 2 @@ -34,18 +41,53 @@ entry: } define internal x86_fp80 @UseLongDoubleSafely(%union.u* byval align 16 %arg) { +; IS__CGSCC____-LABEL: define {{[^@]+}}@UseLongDoubleSafely() +; IS__CGSCC____-NEXT: ret x86_fp80 undef +; %gep = getelementptr inbounds %union.u, %union.u* %arg, i64 0, i32 0 %fp80 = load x86_fp80, x86_fp80* %gep ret x86_fp80 %fp80 } define internal i64 @AccessPaddingOfStruct(%struct.Foo* byval %a) { +; IS__CGSCC____-LABEL: define {{[^@]+}}@AccessPaddingOfStruct() +; IS__CGSCC____-NEXT: ret i64 undef +; %p = bitcast %struct.Foo* %a to i64* %v = load i64, i64* %p ret i64 %v } define internal i64 @CaptureAStruct(%struct.Foo* byval %a) { +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@CaptureAStruct +; IS__CGSCC_OPM-SAME: (%struct.Foo* noalias nofree byval [[A:%.*]]) +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: [[A_PTR:%.*]] = alloca %struct.Foo* +; IS__CGSCC_OPM-NEXT: br label [[LOOP:%.*]] +; IS__CGSCC_OPM: loop: +; IS__CGSCC_OPM-NEXT: [[PHI:%.*]] = phi %struct.Foo* [ null, [[ENTRY:%.*]] ], [ [[GEP:%.*]], [[LOOP]] ] +; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = phi %struct.Foo* [ [[A]], [[ENTRY]] ], [ [[TMP0]], [[LOOP]] ] +; IS__CGSCC_OPM-NEXT: store %struct.Foo* [[PHI]], %struct.Foo** [[A_PTR]], align 8 +; IS__CGSCC_OPM-NEXT: [[GEP]] = getelementptr [[STRUCT_FOO:%.*]], %struct.Foo* [[A]], i64 0 +; IS__CGSCC_OPM-NEXT: br label [[LOOP]] +; +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@CaptureAStruct +; IS__CGSCC_NPM-SAME: (i32 [[TMP0:%.*]], i64 [[TMP1:%.*]]) +; IS__CGSCC_NPM-NEXT: entry: +; IS__CGSCC_NPM-NEXT: [[A_PRIV:%.*]] = alloca [[STRUCT_FOO:%.*]] +; IS__CGSCC_NPM-NEXT: [[A_PRIV_CAST:%.*]] = bitcast %struct.Foo* [[A_PRIV]] to i32* +; IS__CGSCC_NPM-NEXT: store i32 [[TMP0]], i32* [[A_PRIV_CAST]] +; IS__CGSCC_NPM-NEXT: [[A_PRIV_0_1:%.*]] = getelementptr [[STRUCT_FOO]], %struct.Foo* [[A_PRIV]], i32 0, i32 1 +; IS__CGSCC_NPM-NEXT: store i64 [[TMP1]], i64* [[A_PRIV_0_1]] +; IS__CGSCC_NPM-NEXT: [[A_PTR:%.*]] = alloca %struct.Foo* +; IS__CGSCC_NPM-NEXT: br label [[LOOP:%.*]] +; IS__CGSCC_NPM: loop: +; IS__CGSCC_NPM-NEXT: [[PHI:%.*]] = phi %struct.Foo* [ null, [[ENTRY:%.*]] ], [ [[GEP:%.*]], [[LOOP]] ] +; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = phi %struct.Foo* [ [[A_PRIV]], [[ENTRY]] ], [ [[TMP2]], [[LOOP]] ] +; IS__CGSCC_NPM-NEXT: store %struct.Foo* [[PHI]], %struct.Foo** [[A_PTR]], align 8 +; IS__CGSCC_NPM-NEXT: [[GEP]] = getelementptr [[STRUCT_FOO]], %struct.Foo* [[A_PRIV]], i64 0 +; IS__CGSCC_NPM-NEXT: br label [[LOOP]] +; entry: %a_ptr = alloca %struct.Foo* br label %loop diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/inalloca.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/inalloca.ll index c9598b348715..fc2f6ef1724e 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/inalloca.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/inalloca.ll @@ -1,6 +1,8 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=6 < %s | FileCheck %s --check-prefixes=ATTRIBUTOR -; RUN: opt -S -passes='globalopt,attributor' -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=6 < %s | FileCheck %s --check-prefixes=GLOBALOPT_ATTRIBUTOR +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=6 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=6 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" @@ -8,30 +10,25 @@ target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:1 ; Argpromote + sroa should change this to passing the two integers by value. define internal i32 @f(%struct.ss* inalloca %s) { -; ATTRIBUTOR-LABEL: define {{[^@]+}}@f -; ATTRIBUTOR-SAME: (%struct.ss* inalloca noalias nocapture nofree nonnull align 4 dereferenceable(8) [[S:%.*]]) -; ATTRIBUTOR-NEXT: entry: -; ATTRIBUTOR-NEXT: [[F0:%.*]] = getelementptr [[STRUCT_SS:%.*]], %struct.ss* [[S]], i32 0, i32 0 -; ATTRIBUTOR-NEXT: [[F1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1 -; ATTRIBUTOR-NEXT: [[A:%.*]] = load i32, i32* [[F0]], align 4 -; ATTRIBUTOR-NEXT: [[B:%.*]] = load i32, i32* [[F1]], align 4 -; ATTRIBUTOR-NEXT: [[R:%.*]] = add i32 [[A]], [[B]] -; ATTRIBUTOR-NEXT: ret i32 [[R]] +; IS__TUNIT____-LABEL: define {{[^@]+}}@f +; IS__TUNIT____-SAME: (%struct.ss* inalloca noalias nocapture nofree nonnull align 4 dereferenceable(8) [[S:%.*]]) +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: [[F0:%.*]] = getelementptr [[STRUCT_SS:%.*]], %struct.ss* [[S]], i32 0, i32 0 +; IS__TUNIT____-NEXT: [[F1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1 +; IS__TUNIT____-NEXT: [[A:%.*]] = load i32, i32* [[F0]], align 4 +; IS__TUNIT____-NEXT: [[B:%.*]] = load i32, i32* [[F1]], align 4 +; IS__TUNIT____-NEXT: [[R:%.*]] = add i32 [[A]], [[B]] +; IS__TUNIT____-NEXT: ret i32 [[R]] ; -; GLOBALOPT_ATTRIBUTOR-LABEL: define {{[^@]+}}@f -; GLOBALOPT_ATTRIBUTOR-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]]) unnamed_addr -; GLOBALOPT_ATTRIBUTOR-NEXT: entry: -; GLOBALOPT_ATTRIBUTOR-NEXT: [[S_PRIV:%.*]] = alloca [[STRUCT_SS:%.*]] -; GLOBALOPT_ATTRIBUTOR-NEXT: [[S_PRIV_CAST:%.*]] = bitcast %struct.ss* [[S_PRIV]] to i32* -; GLOBALOPT_ATTRIBUTOR-NEXT: store i32 [[TMP0]], i32* [[S_PRIV_CAST]] -; GLOBALOPT_ATTRIBUTOR-NEXT: [[S_PRIV_0_1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S_PRIV]], i32 0, i32 1 -; GLOBALOPT_ATTRIBUTOR-NEXT: store i32 [[TMP1]], i32* [[S_PRIV_0_1]] -; GLOBALOPT_ATTRIBUTOR-NEXT: [[F0:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S_PRIV]], i32 0, i32 0 -; GLOBALOPT_ATTRIBUTOR-NEXT: [[F1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S_PRIV]], i32 0, i32 1 -; GLOBALOPT_ATTRIBUTOR-NEXT: [[A:%.*]] = load i32, i32* [[F0]], align 4 -; GLOBALOPT_ATTRIBUTOR-NEXT: [[B:%.*]] = load i32, i32* [[F1]], align 4 -; GLOBALOPT_ATTRIBUTOR-NEXT: [[R:%.*]] = add i32 [[A]], [[B]] -; GLOBALOPT_ATTRIBUTOR-NEXT: ret i32 [[R]] +; IS__CGSCC____-LABEL: define {{[^@]+}}@f +; IS__CGSCC____-SAME: (%struct.ss* inalloca nocapture nofree nonnull align 4 dereferenceable(8) [[S:%.*]]) +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: [[F0:%.*]] = getelementptr [[STRUCT_SS:%.*]], %struct.ss* [[S]], i32 0, i32 0 +; IS__CGSCC____-NEXT: [[F1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1 +; IS__CGSCC____-NEXT: [[A:%.*]] = load i32, i32* [[F0]], align 4 +; IS__CGSCC____-NEXT: [[B:%.*]] = load i32, i32* [[F1]], align 4 +; IS__CGSCC____-NEXT: [[R:%.*]] = add i32 [[A]], [[B]] +; IS__CGSCC____-NEXT: ret i32 [[R]] ; entry: %f0 = getelementptr %struct.ss, %struct.ss* %s, i32 0, i32 0 @@ -43,29 +40,25 @@ entry: } define i32 @main() { -; ATTRIBUTOR-LABEL: define {{[^@]+}}@main() -; ATTRIBUTOR-NEXT: entry: -; ATTRIBUTOR-NEXT: [[S:%.*]] = alloca inalloca [[STRUCT_SS:%.*]] -; ATTRIBUTOR-NEXT: [[F0:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 0 -; ATTRIBUTOR-NEXT: [[F1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1 -; ATTRIBUTOR-NEXT: store i32 1, i32* [[F0]], align 4 -; ATTRIBUTOR-NEXT: store i32 2, i32* [[F1]], align 4 -; ATTRIBUTOR-NEXT: [[R:%.*]] = call i32 @f(%struct.ss* inalloca noalias nocapture nofree nonnull align 4 dereferenceable(8) [[S]]) -; ATTRIBUTOR-NEXT: ret i32 [[R]] +; IS__TUNIT____-LABEL: define {{[^@]+}}@main() +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: [[S:%.*]] = alloca inalloca [[STRUCT_SS:%.*]] +; IS__TUNIT____-NEXT: [[F0:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 0 +; IS__TUNIT____-NEXT: [[F1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1 +; IS__TUNIT____-NEXT: store i32 1, i32* [[F0]], align 4 +; IS__TUNIT____-NEXT: store i32 2, i32* [[F1]], align 4 +; IS__TUNIT____-NEXT: [[R:%.*]] = call i32 @f(%struct.ss* inalloca noalias nocapture nofree nonnull align 4 dereferenceable(8) [[S]]) +; IS__TUNIT____-NEXT: ret i32 [[R]] ; -; GLOBALOPT_ATTRIBUTOR-LABEL: define {{[^@]+}}@main() local_unnamed_addr -; GLOBALOPT_ATTRIBUTOR-NEXT: entry: -; GLOBALOPT_ATTRIBUTOR-NEXT: [[S:%.*]] = alloca inalloca [[STRUCT_SS:%.*]] -; GLOBALOPT_ATTRIBUTOR-NEXT: [[F0:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 0 -; GLOBALOPT_ATTRIBUTOR-NEXT: [[F1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1 -; GLOBALOPT_ATTRIBUTOR-NEXT: store i32 1, i32* [[F0]], align 4 -; GLOBALOPT_ATTRIBUTOR-NEXT: store i32 2, i32* [[F1]], align 4 -; GLOBALOPT_ATTRIBUTOR-NEXT: [[S_CAST:%.*]] = bitcast %struct.ss* [[S]] to i32* -; GLOBALOPT_ATTRIBUTOR-NEXT: [[TMP0:%.*]] = load i32, i32* [[S_CAST]], align 1 -; GLOBALOPT_ATTRIBUTOR-NEXT: [[S_0_1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1 -; GLOBALOPT_ATTRIBUTOR-NEXT: [[TMP1:%.*]] = load i32, i32* [[S_0_1]], align 1 -; GLOBALOPT_ATTRIBUTOR-NEXT: [[R:%.*]] = call fastcc i32 @f(i32 [[TMP0]], i32 [[TMP1]]) -; GLOBALOPT_ATTRIBUTOR-NEXT: ret i32 [[R]] +; IS__CGSCC____-LABEL: define {{[^@]+}}@main() +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: [[S:%.*]] = alloca inalloca [[STRUCT_SS:%.*]] +; IS__CGSCC____-NEXT: [[F0:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 0 +; IS__CGSCC____-NEXT: [[F1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1 +; IS__CGSCC____-NEXT: store i32 1, i32* [[F0]], align 4 +; IS__CGSCC____-NEXT: store i32 2, i32* [[F1]], align 4 +; IS__CGSCC____-NEXT: [[R:%.*]] = call i32 @f(%struct.ss* inalloca noalias nofree nonnull align 4 dereferenceable(8) [[S]]) +; IS__CGSCC____-NEXT: ret i32 [[R]] ; entry: %S = alloca inalloca %struct.ss @@ -79,19 +72,20 @@ entry: ; Argpromote can't promote %a because of the icmp use. define internal i1 @g(%struct.ss* %a, %struct.ss* inalloca %b) nounwind { +; IS__CGSCC____-LABEL: define {{[^@]+}}@g +; IS__CGSCC____-SAME: (%struct.ss* nocapture nofree readnone [[A:%.*]], %struct.ss* inalloca nocapture nofree writeonly [[B:%.*]]) +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: ret i1 undef +; entry: %c = icmp eq %struct.ss* %a, %b ret i1 %c } define i32 @test() { -; ATTRIBUTOR-LABEL: define {{[^@]+}}@test() -; ATTRIBUTOR-NEXT: entry: -; ATTRIBUTOR-NEXT: ret i32 0 -; -; GLOBALOPT_ATTRIBUTOR-LABEL: define {{[^@]+}}@test() local_unnamed_addr -; GLOBALOPT_ATTRIBUTOR-NEXT: entry: -; GLOBALOPT_ATTRIBUTOR-NEXT: ret i32 0 +; CHECK-LABEL: define {{[^@]+}}@test() +; CHECK-NEXT: entry: +; CHECK-NEXT: ret i32 0 ; entry: %S = alloca inalloca %struct.ss diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/live_called_from_dead.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/live_called_from_dead.ll index c69842119ec6..1f034c8404fe 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/live_called_from_dead.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/live_called_from_dead.ll @@ -1,13 +1,9 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes -; RUN: opt -S -basicaa -attributor -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=4 < %s | FileCheck %s --check-prefixes=CHECK,OLDPM,OLDPM_MODULE -; RUN: opt -S -basicaa -attributor-cgscc -attributor-disable=false < %s | FileCheck %s --check-prefixes=CHECK,OLDPM,OLDPM_CGSCC -; RUN: opt -S -passes='attributor' -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=4 < %s | FileCheck %s --check-prefixes=CHECK,NEWPM,NEWPM_MODULE -; RUN: opt -S -passes='attributor-cgscc' -aa-pipeline='basic-aa' -attributor-disable=false < %s | FileCheck %s --check-prefixes=CHECK,NEWPM,NEWPM_CGSCC +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=4 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=4 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 -; OLDPM_MODULE-NOT: @dead -; NEWPM_MODULE-NOT: @dead -; OLDPM_CGSCC-NOT: @dead -; NEWPM_CGSCC-NOT: @dead define internal void @dead() { call i32 @test(i32* null, i32* null) @@ -15,23 +11,23 @@ define internal void @dead() { } define internal i32 @test(i32* %X, i32* %Y) { -; OLDPM_CGSCC-LABEL: define {{[^@]+}}@test -; OLDPM_CGSCC-SAME: (i32* noalias nocapture nofree writeonly align 4 [[X:%.*]]) -; OLDPM_CGSCC-NEXT: br i1 true, label [[LIVE:%.*]], label [[DEAD:%.*]] -; OLDPM_CGSCC: live: -; OLDPM_CGSCC-NEXT: store i32 0, i32* [[X]], align 4 -; OLDPM_CGSCC-NEXT: ret i32 undef -; OLDPM_CGSCC: dead: -; OLDPM_CGSCC-NEXT: unreachable +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test +; IS__CGSCC_OPM-SAME: (i32* noalias nocapture nofree writeonly align 4 [[X:%.*]]) +; IS__CGSCC_OPM-NEXT: br i1 true, label [[LIVE:%.*]], label [[DEAD:%.*]] +; IS__CGSCC_OPM: live: +; IS__CGSCC_OPM-NEXT: store i32 0, i32* [[X]], align 4 +; IS__CGSCC_OPM-NEXT: ret i32 undef +; IS__CGSCC_OPM: dead: +; IS__CGSCC_OPM-NEXT: unreachable ; -; NEWPM_CGSCC-LABEL: define {{[^@]+}}@test -; NEWPM_CGSCC-SAME: (i32* noalias nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[X:%.*]]) -; NEWPM_CGSCC-NEXT: br i1 true, label [[LIVE:%.*]], label [[DEAD:%.*]] -; NEWPM_CGSCC: live: -; NEWPM_CGSCC-NEXT: store i32 0, i32* [[X]], align 4 -; NEWPM_CGSCC-NEXT: ret i32 undef -; NEWPM_CGSCC: dead: -; NEWPM_CGSCC-NEXT: unreachable +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test +; IS__CGSCC_NPM-SAME: (i32* noalias nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[X:%.*]]) +; IS__CGSCC_NPM-NEXT: br i1 true, label [[LIVE:%.*]], label [[DEAD:%.*]] +; IS__CGSCC_NPM: live: +; IS__CGSCC_NPM-NEXT: store i32 0, i32* [[X]], align 4 +; IS__CGSCC_NPM-NEXT: ret i32 undef +; IS__CGSCC_NPM: dead: +; IS__CGSCC_NPM-NEXT: unreachable ; br i1 true, label %live, label %dead live: @@ -44,17 +40,17 @@ dead: } define internal i32 @caller(i32* %B) { -; OLDPM_CGSCC-LABEL: define {{[^@]+}}@caller() -; OLDPM_CGSCC-NEXT: [[A:%.*]] = alloca i32 -; OLDPM_CGSCC-NEXT: store i32 1, i32* [[A]], align 4 -; OLDPM_CGSCC-NEXT: [[C:%.*]] = call i32 @test(i32* noalias nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[A]]) -; OLDPM_CGSCC-NEXT: ret i32 0 +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@caller() +; IS__CGSCC_OPM-NEXT: [[A:%.*]] = alloca i32 +; IS__CGSCC_OPM-NEXT: store i32 1, i32* [[A]], align 4 +; IS__CGSCC_OPM-NEXT: [[C:%.*]] = call i32 @test(i32* noalias nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[A]]) +; IS__CGSCC_OPM-NEXT: ret i32 0 ; -; NEWPM_CGSCC-LABEL: define {{[^@]+}}@caller() -; NEWPM_CGSCC-NEXT: [[A:%.*]] = alloca i32 -; NEWPM_CGSCC-NEXT: store i32 1, i32* [[A]], align 4 -; NEWPM_CGSCC-NEXT: [[C:%.*]] = call i32 @test(i32* noalias nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[A]]) -; NEWPM_CGSCC-NEXT: ret i32 undef +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@caller() +; IS__CGSCC_NPM-NEXT: [[A:%.*]] = alloca i32 +; IS__CGSCC_NPM-NEXT: store i32 1, i32* [[A]], align 4 +; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call i32 @test(i32* noalias nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[A]]) +; IS__CGSCC_NPM-NEXT: ret i32 undef ; %A = alloca i32 store i32 1, i32* %A diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/live_called_from_dead_2.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/live_called_from_dead_2.ll index 429a3a7b7b43..d3892d2093a0 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/live_called_from_dead_2.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/live_called_from_dead_2.ll @@ -1,13 +1,9 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes -; RUN: opt -S -basicaa -attributor -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=7 < %s | FileCheck %s --check-prefixes=CHECK,OLDPM,OLDPM_MODULE -; RUN: opt -S -basicaa -attributor-cgscc -attributor-disable=false < %s | FileCheck %s --check-prefixes=CHECK,OLDPM,OLDPM_CGSCC -; RUN: opt -S -passes='attributor' -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=7 < %s | FileCheck %s --check-prefixes=CHECK,NEWPM,NEWPM_MODULE -; RUN: opt -S -passes='attributor-cgscc' -aa-pipeline='basic-aa' -attributor-disable=false < %s | FileCheck %s --check-prefixes=CHECK,NEWPM,NEWPM_CGSCC +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=7 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=7 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 -; OLDPM_MODULE-NOT: @dead -; NEWPM_MODULE-NOT: @dead -; OLDPM_CGSCC-NOT: @dead -; NEWPM_CGSCC-NOT: @dead define internal void @dead() { call i32 @test(i32* null, i32* null) @@ -15,41 +11,23 @@ define internal void @dead() { } define internal i32 @test(i32* %X, i32* %Y) { -; OLDPM_MODULE-LABEL: define {{[^@]+}}@test -; OLDPM_MODULE-SAME: (i32* noalias nocapture nofree writeonly align 4 [[X:%.*]]) -; OLDPM_MODULE-NEXT: br i1 true, label [[LIVE:%.*]], label [[DEAD:%.*]] -; OLDPM_MODULE: live: -; OLDPM_MODULE-NEXT: store i32 0, i32* [[X]], align 4 -; OLDPM_MODULE-NEXT: ret i32 undef -; OLDPM_MODULE: dead: -; OLDPM_MODULE-NEXT: unreachable +; IS__TUNIT____-LABEL: define {{[^@]+}}@test +; IS__TUNIT____-SAME: (i32* noalias nocapture nofree writeonly align 4 [[X:%.*]]) +; IS__TUNIT____-NEXT: br i1 true, label [[LIVE:%.*]], label [[DEAD:%.*]] +; IS__TUNIT____: live: +; IS__TUNIT____-NEXT: store i32 0, i32* [[X]], align 4 +; IS__TUNIT____-NEXT: ret i32 undef +; IS__TUNIT____: dead: +; IS__TUNIT____-NEXT: unreachable ; -; OLDPM_CGSCC-LABEL: define {{[^@]+}}@test -; OLDPM_CGSCC-SAME: (i32* nocapture nofree writeonly [[X:%.*]]) -; OLDPM_CGSCC-NEXT: br i1 true, label [[LIVE:%.*]], label [[DEAD:%.*]] -; OLDPM_CGSCC: live: -; OLDPM_CGSCC-NEXT: store i32 0, i32* [[X]] -; OLDPM_CGSCC-NEXT: ret i32 undef -; OLDPM_CGSCC: dead: -; OLDPM_CGSCC-NEXT: unreachable -; -; NEWPM_MODULE-LABEL: define {{[^@]+}}@test -; NEWPM_MODULE-SAME: (i32* noalias nocapture nofree writeonly align 4 [[X:%.*]]) -; NEWPM_MODULE-NEXT: br i1 true, label [[LIVE:%.*]], label [[DEAD:%.*]] -; NEWPM_MODULE: live: -; NEWPM_MODULE-NEXT: store i32 0, i32* [[X]], align 4 -; NEWPM_MODULE-NEXT: ret i32 undef -; NEWPM_MODULE: dead: -; NEWPM_MODULE-NEXT: unreachable -; -; NEWPM_CGSCC-LABEL: define {{[^@]+}}@test -; NEWPM_CGSCC-SAME: (i32* nocapture nofree writeonly [[X:%.*]]) -; NEWPM_CGSCC-NEXT: br i1 true, label [[LIVE:%.*]], label [[DEAD:%.*]] -; NEWPM_CGSCC: live: -; NEWPM_CGSCC-NEXT: store i32 0, i32* [[X]] -; NEWPM_CGSCC-NEXT: ret i32 undef -; NEWPM_CGSCC: dead: -; NEWPM_CGSCC-NEXT: unreachable +; IS__CGSCC____-LABEL: define {{[^@]+}}@test +; IS__CGSCC____-SAME: (i32* nocapture nofree writeonly [[X:%.*]]) +; IS__CGSCC____-NEXT: br i1 true, label [[LIVE:%.*]], label [[DEAD:%.*]] +; IS__CGSCC____: live: +; IS__CGSCC____-NEXT: store i32 0, i32* [[X]] +; IS__CGSCC____-NEXT: ret i32 undef +; IS__CGSCC____: dead: +; IS__CGSCC____-NEXT: unreachable ; br i1 true, label %live, label %dead live: @@ -62,33 +40,26 @@ dead: } define internal i32 @caller(i32* %B) { -; OLDPM_MODULE-LABEL: define {{[^@]+}}@caller -; OLDPM_MODULE-SAME: (i32* noalias nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[B:%.*]]) -; OLDPM_MODULE-NEXT: [[A:%.*]] = alloca i32 -; OLDPM_MODULE-NEXT: store i32 1, i32* [[A]], align 4 -; OLDPM_MODULE-NEXT: [[C:%.*]] = call i32 @test(i32* noalias nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[B]]) -; OLDPM_MODULE-NEXT: ret i32 undef +; IS__TUNIT____-LABEL: define {{[^@]+}}@caller +; IS__TUNIT____-SAME: (i32* noalias nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[B:%.*]]) +; IS__TUNIT____-NEXT: [[A:%.*]] = alloca i32 +; IS__TUNIT____-NEXT: store i32 1, i32* [[A]], align 4 +; IS__TUNIT____-NEXT: [[C:%.*]] = call i32 @test(i32* noalias nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[B]]) +; IS__TUNIT____-NEXT: ret i32 undef ; -; OLDPM_CGSCC-LABEL: define {{[^@]+}}@caller -; OLDPM_CGSCC-SAME: (i32* nocapture nofree writeonly [[B:%.*]]) -; OLDPM_CGSCC-NEXT: [[A:%.*]] = alloca i32 -; OLDPM_CGSCC-NEXT: store i32 1, i32* [[A]], align 4 -; OLDPM_CGSCC-NEXT: [[C:%.*]] = call i32 @test(i32* nocapture nofree writeonly [[B]]) -; OLDPM_CGSCC-NEXT: ret i32 0 +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@caller +; IS__CGSCC_OPM-SAME: (i32* nocapture nofree writeonly [[B:%.*]]) +; IS__CGSCC_OPM-NEXT: [[A:%.*]] = alloca i32 +; IS__CGSCC_OPM-NEXT: store i32 1, i32* [[A]], align 4 +; IS__CGSCC_OPM-NEXT: [[C:%.*]] = call i32 @test(i32* nocapture nofree writeonly [[B]]) +; IS__CGSCC_OPM-NEXT: ret i32 0 ; -; NEWPM_MODULE-LABEL: define {{[^@]+}}@caller -; NEWPM_MODULE-SAME: (i32* noalias nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[B:%.*]]) -; NEWPM_MODULE-NEXT: [[A:%.*]] = alloca i32 -; NEWPM_MODULE-NEXT: store i32 1, i32* [[A]], align 4 -; NEWPM_MODULE-NEXT: [[C:%.*]] = call i32 @test(i32* noalias nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[B]]) -; NEWPM_MODULE-NEXT: ret i32 undef -; -; NEWPM_CGSCC-LABEL: define {{[^@]+}}@caller -; NEWPM_CGSCC-SAME: (i32* nocapture nofree writeonly [[B:%.*]]) -; NEWPM_CGSCC-NEXT: [[A:%.*]] = alloca i32 -; NEWPM_CGSCC-NEXT: store i32 1, i32* [[A]], align 4 -; NEWPM_CGSCC-NEXT: [[C:%.*]] = call i32 @test(i32* nocapture nofree writeonly [[B]]) -; NEWPM_CGSCC-NEXT: ret i32 undef +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@caller +; IS__CGSCC_NPM-SAME: (i32* nocapture nofree writeonly [[B:%.*]]) +; IS__CGSCC_NPM-NEXT: [[A:%.*]] = alloca i32 +; IS__CGSCC_NPM-NEXT: store i32 1, i32* [[A]], align 4 +; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call i32 @test(i32* nocapture nofree writeonly [[B]]) +; IS__CGSCC_NPM-NEXT: ret i32 undef ; %A = alloca i32 store i32 1, i32* %A @@ -97,29 +68,17 @@ define internal i32 @caller(i32* %B) { } define i32 @callercaller() { -; OLDPM_MODULE-LABEL: define {{[^@]+}}@callercaller() -; OLDPM_MODULE-NEXT: [[B:%.*]] = alloca i32 -; OLDPM_MODULE-NEXT: store i32 2, i32* [[B]], align 4 -; OLDPM_MODULE-NEXT: [[X:%.*]] = call i32 @caller(i32* noalias nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[B]]) -; OLDPM_MODULE-NEXT: ret i32 0 +; IS__TUNIT____-LABEL: define {{[^@]+}}@callercaller() +; IS__TUNIT____-NEXT: [[B:%.*]] = alloca i32 +; IS__TUNIT____-NEXT: store i32 2, i32* [[B]], align 4 +; IS__TUNIT____-NEXT: [[X:%.*]] = call i32 @caller(i32* noalias nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[B]]) +; IS__TUNIT____-NEXT: ret i32 0 ; -; OLDPM_CGSCC-LABEL: define {{[^@]+}}@callercaller() -; OLDPM_CGSCC-NEXT: [[B:%.*]] = alloca i32 -; OLDPM_CGSCC-NEXT: store i32 2, i32* [[B]], align 4 -; OLDPM_CGSCC-NEXT: [[X:%.*]] = call i32 @caller(i32* noalias nofree nonnull writeonly align 4 dereferenceable(4) [[B]]) -; OLDPM_CGSCC-NEXT: ret i32 0 -; -; NEWPM_MODULE-LABEL: define {{[^@]+}}@callercaller() -; NEWPM_MODULE-NEXT: [[B:%.*]] = alloca i32 -; NEWPM_MODULE-NEXT: store i32 2, i32* [[B]], align 4 -; NEWPM_MODULE-NEXT: [[X:%.*]] = call i32 @caller(i32* noalias nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[B]]) -; NEWPM_MODULE-NEXT: ret i32 0 -; -; NEWPM_CGSCC-LABEL: define {{[^@]+}}@callercaller() -; NEWPM_CGSCC-NEXT: [[B:%.*]] = alloca i32 -; NEWPM_CGSCC-NEXT: store i32 2, i32* [[B]], align 4 -; NEWPM_CGSCC-NEXT: [[X:%.*]] = call i32 @caller(i32* noalias nofree nonnull writeonly align 4 dereferenceable(4) [[B]]) -; NEWPM_CGSCC-NEXT: ret i32 0 +; IS__CGSCC____-LABEL: define {{[^@]+}}@callercaller() +; IS__CGSCC____-NEXT: [[B:%.*]] = alloca i32 +; IS__CGSCC____-NEXT: store i32 2, i32* [[B]], align 4 +; IS__CGSCC____-NEXT: [[X:%.*]] = call i32 @caller(i32* noalias nofree nonnull writeonly align 4 dereferenceable(4) [[B]]) +; IS__CGSCC____-NEXT: ret i32 0 ; %B = alloca i32 store i32 2, i32* %B diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/musttail.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/musttail.ll index 89ee21519e78..0fc379c705f1 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/musttail.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/musttail.ll @@ -1,5 +1,8 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=1 < %s | FileCheck %s +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 ; PR36543 ; Don't promote arguments of musttail callee @@ -45,6 +48,16 @@ define i32 @foo(%T* %p, i32 %v) { } define internal i32 @test2(%T* %p, i32 %p2) { +; IS__CGSCC____-LABEL: define {{[^@]+}}@test2 +; IS__CGSCC____-SAME: (%T* nocapture nofree readonly [[P:%.*]], i32 [[P2:%.*]]) +; IS__CGSCC____-NEXT: [[A_GEP:%.*]] = getelementptr [[T:%.*]], %T* [[P]], i64 0, i32 3 +; IS__CGSCC____-NEXT: [[B_GEP:%.*]] = getelementptr [[T]], %T* [[P]], i64 0, i32 2 +; IS__CGSCC____-NEXT: [[A:%.*]] = load i32, i32* [[A_GEP]], align 4 +; IS__CGSCC____-NEXT: [[B:%.*]] = load i32, i32* [[B_GEP]], align 4 +; IS__CGSCC____-NEXT: [[V:%.*]] = add i32 [[A]], [[B]] +; IS__CGSCC____-NEXT: [[CA:%.*]] = musttail call i32 @foo(%T* undef, i32 [[V]]) +; IS__CGSCC____-NEXT: ret i32 [[CA]] +; %a.gep = getelementptr %T, %T* %p, i64 0, i32 3 %b.gep = getelementptr %T, %T* %p, i64 0, i32 2 %a = load i32, i32* %a.gep @@ -55,9 +68,14 @@ define internal i32 @test2(%T* %p, i32 %p2) { } define i32 @caller2(%T* %g) { -; CHECK-LABEL: define {{[^@]+}}@caller2 -; CHECK-SAME: (%T* nocapture nofree readnone [[G:%.*]]) -; CHECK-NEXT: ret i32 0 +; IS__TUNIT____-LABEL: define {{[^@]+}}@caller2 +; IS__TUNIT____-SAME: (%T* nocapture nofree readnone [[G:%.*]]) +; IS__TUNIT____-NEXT: ret i32 0 +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@caller2 +; IS__CGSCC____-SAME: (%T* nocapture nofree readonly [[G:%.*]]) +; IS__CGSCC____-NEXT: [[V:%.*]] = call i32 @test2(%T* nocapture nofree readonly [[G]], i32 0) +; IS__CGSCC____-NEXT: ret i32 [[V]] ; %v = call i32 @test2(%T* %g, i32 0) ret i32 %v @@ -100,10 +118,15 @@ define internal i32 @test2b(%T* %p, i32 %p2) { } define i32 @caller2b(%T* %g) { -; CHECK-LABEL: define {{[^@]+}}@caller2b -; CHECK-SAME: (%T* nocapture nofree readonly [[G:%.*]]) -; CHECK-NEXT: [[V:%.*]] = call i32 @test2b(%T* nocapture nofree readonly [[G]], i32 undef) -; CHECK-NEXT: ret i32 0 +; IS__TUNIT____-LABEL: define {{[^@]+}}@caller2b +; IS__TUNIT____-SAME: (%T* nocapture nofree readonly [[G:%.*]]) +; IS__TUNIT____-NEXT: [[V:%.*]] = call i32 @test2b(%T* nocapture nofree readonly [[G]], i32 undef) +; IS__TUNIT____-NEXT: ret i32 0 +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@caller2b +; IS__CGSCC____-SAME: (%T* nocapture nofree readonly [[G:%.*]]) +; IS__CGSCC____-NEXT: [[V:%.*]] = call i32 @test2b(%T* nocapture nofree readonly [[G]], i32 0) +; IS__CGSCC____-NEXT: ret i32 [[V]] ; %v = call i32 @test2b(%T* %g, i32 0) ret i32 %v diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/naked_functions.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/naked_functions.ll index 4bfe138f4b6e..92cb7efb7bd2 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/naked_functions.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/naked_functions.ll @@ -1,5 +1,8 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=1 < %s | FileCheck %s +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 ; Don't promote paramaters of/arguments to naked functions diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/nonzero-address-spaces.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/nonzero-address-spaces.ll index d08969c0a262..04e8bd6bdc8b 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/nonzero-address-spaces.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/nonzero-address-spaces.ll @@ -1,5 +1,8 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=1 < %s | FileCheck %s +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 ; ArgumentPromotion should preserve the default function address space ; from the data layout. diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/pr27568.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/pr27568.ll index f2ff8dc63279..d7aafae2d158 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/pr27568.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/pr27568.ll @@ -1,5 +1,8 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=1 < %s | FileCheck %s +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 target triple = "x86_64-pc-windows-msvc" define internal void @callee(i8*) { diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/pr3085.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/pr3085.ll deleted file mode 100644 index 5b8b7da46a47..000000000000 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/pr3085.ll +++ /dev/null @@ -1,1945 +0,0 @@ -; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes -; RUN: opt -disable-output -passes=attributor -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=1 < %s -; PR 3085 - - %struct.Lit = type { i8 } - -define fastcc %struct.Lit* @import_lit(i32 %lit) nounwind { -entry: - br i1 false, label %bb, label %bb1 - -bb: ; preds = %entry - unreachable - -bb1: ; preds = %entry - br label %bb3 - -bb2: ; preds = %bb3 - br label %bb3 - -bb3: ; preds = %bb2, %bb1 - br i1 false, label %bb2, label %bb6 - -bb6: ; preds = %bb3 - br i1 false, label %bb.i.i, label %bb1.i.i - -bb.i.i: ; preds = %bb6 - br label %int2lit.exit - -bb1.i.i: ; preds = %bb6 - br label %int2lit.exit - -int2lit.exit: ; preds = %bb1.i.i, %bb.i.i - ret %struct.Lit* null -} - -define fastcc i32 @picosat_main(i32 %argc, i8** %argv) nounwind { -entry: - br i1 false, label %bb.i, label %picosat_time_stamp.exit - -bb.i: ; preds = %entry - br label %picosat_time_stamp.exit - -picosat_time_stamp.exit: ; preds = %bb.i, %entry - br label %bb108 - -bb: ; preds = %bb108 - br i1 false, label %bb1, label %bb2 - -bb1: ; preds = %bb - br label %bb106 - -bb2: ; preds = %bb - br i1 false, label %bb3, label %bb4 - -bb3: ; preds = %bb2 - br label %bb106 - -bb4: ; preds = %bb2 - br i1 false, label %bb5, label %bb6 - -bb5: ; preds = %bb4 - br label %bb106 - -bb6: ; preds = %bb4 - br i1 false, label %bb7, label %bb8 - -bb7: ; preds = %bb6 - br label %bb106 - -bb8: ; preds = %bb6 - br i1 false, label %bb106, label %bb10 - -bb10: ; preds = %bb8 - br i1 false, label %bb106, label %bb12 - -bb12: ; preds = %bb10 - br i1 false, label %bb106, label %bb14 - -bb14: ; preds = %bb12 - br i1 false, label %bb15, label %bb19 - -bb15: ; preds = %bb14 - br i1 false, label %bb16, label %bb17 - -bb16: ; preds = %bb15 - br label %bb106 - -bb17: ; preds = %bb15 - br label %bb106 - -bb19: ; preds = %bb14 - br i1 false, label %bb20, label %bb28 - -bb20: ; preds = %bb19 - br i1 false, label %bb21, label %bb22 - -bb21: ; preds = %bb20 - br label %bb106 - -bb22: ; preds = %bb20 - br i1 false, label %bb106, label %bb24 - -bb24: ; preds = %bb22 - br i1 false, label %bb106, label %bb26 - -bb26: ; preds = %bb24 - br label %bb106 - -bb28: ; preds = %bb19 - br i1 false, label %bb29, label %bb35 - -bb29: ; preds = %bb28 - br i1 false, label %bb30, label %bb31 - -bb30: ; preds = %bb29 - br label %bb106 - -bb31: ; preds = %bb29 - br i1 false, label %bb32, label %bb33 - -bb32: ; preds = %bb31 - br label %bb106 - -bb33: ; preds = %bb31 - br label %bb106 - -bb35: ; preds = %bb28 - br i1 false, label %bb36, label %bb40 - -bb36: ; preds = %bb35 - br i1 false, label %bb37, label %bb38 - -bb37: ; preds = %bb36 - br label %bb106 - -bb38: ; preds = %bb36 - br label %bb106 - -bb40: ; preds = %bb35 - br i1 false, label %bb41, label %bb49 - -bb41: ; preds = %bb40 - br i1 false, label %bb43, label %bb42 - -bb42: ; preds = %bb41 - br label %bb106 - -bb43: ; preds = %bb41 - br i1 false, label %bb44, label %bb45 - -bb44: ; preds = %bb43 - br label %bb106 - -bb45: ; preds = %bb43 - br i1 false, label %bb46, label %bb47 - -bb46: ; preds = %bb45 - br label %bb106 - -bb47: ; preds = %bb45 - br label %bb106 - -bb49: ; preds = %bb40 - br i1 false, label %bb50, label %bb56 - -bb50: ; preds = %bb49 - br i1 false, label %bb52, label %bb51 - -bb51: ; preds = %bb50 - br label %bb106 - -bb52: ; preds = %bb50 - br i1 false, label %bb53, label %bb54 - -bb53: ; preds = %bb52 - br label %bb106 - -bb54: ; preds = %bb52 - br label %bb106 - -bb56: ; preds = %bb49 - br i1 false, label %bb57, label %bb63 - -bb57: ; preds = %bb56 - br i1 false, label %bb59, label %bb58 - -bb58: ; preds = %bb57 - br label %bb106 - -bb59: ; preds = %bb57 - br i1 false, label %bb60, label %bb61 - -bb60: ; preds = %bb59 - br label %bb106 - -bb61: ; preds = %bb59 - br label %bb106 - -bb63: ; preds = %bb56 - br i1 false, label %bb64, label %bb70 - -bb64: ; preds = %bb63 - br i1 false, label %bb66, label %bb65 - -bb65: ; preds = %bb64 - br label %bb106 - -bb66: ; preds = %bb64 - br i1 false, label %bb67, label %bb68 - -bb67: ; preds = %bb66 - br label %bb106 - -bb68: ; preds = %bb66 - br label %bb106 - -bb70: ; preds = %bb63 - br i1 false, label %bb71, label %bb79 - -bb71: ; preds = %bb70 - br i1 false, label %bb73, label %bb72 - -bb72: ; preds = %bb71 - br label %bb106 - -bb73: ; preds = %bb71 - br i1 false, label %bb74, label %bb75 - -bb74: ; preds = %bb73 - br label %bb106 - -bb75: ; preds = %bb73 - br i1 false, label %bb76, label %bb77 - -bb76: ; preds = %bb75 - br label %bb106 - -bb77: ; preds = %bb75 - br label %bb106 - -bb79: ; preds = %bb70 - br i1 false, label %bb80, label %bb86 - -bb80: ; preds = %bb79 - br i1 false, label %bb82, label %bb81 - -bb81: ; preds = %bb80 - br label %bb106 - -bb82: ; preds = %bb80 - br i1 false, label %bb83, label %bb84 - -bb83: ; preds = %bb82 - br label %bb106 - -bb84: ; preds = %bb82 - br label %bb106 - -bb86: ; preds = %bb79 - br i1 false, label %bb87, label %bb93 - -bb87: ; preds = %bb86 - br i1 false, label %bb89, label %bb88 - -bb88: ; preds = %bb87 - br label %bb106 - -bb89: ; preds = %bb87 - br i1 false, label %bb90, label %bb91 - -bb90: ; preds = %bb89 - br label %bb106 - -bb91: ; preds = %bb89 - br label %bb106 - -bb93: ; preds = %bb86 - br i1 false, label %bb94, label %bb95 - -bb94: ; preds = %bb93 - br label %bb106 - -bb95: ; preds = %bb93 - br i1 false, label %bb98, label %bb97 - -bb97: ; preds = %bb95 - br label %bb106 - -bb98: ; preds = %bb95 - br i1 false, label %bb103, label %bb1.i24 - -bb1.i24: ; preds = %bb98 - br i1 false, label %bb99, label %bb103 - -bb99: ; preds = %bb1.i24 - br i1 false, label %bb101, label %bb100 - -bb100: ; preds = %bb99 - br label %bb102 - -bb101: ; preds = %bb99 - br label %bb102 - -bb102: ; preds = %bb101, %bb100 - br label %bb106 - -bb103: ; preds = %bb1.i24, %bb98 - br i1 false, label %bb104, label %bb105 - -bb104: ; preds = %bb103 - br label %bb106 - -bb105: ; preds = %bb103 - br label %bb106 - -bb106: ; preds = %bb105, %bb104, %bb102, %bb97, %bb94, %bb91, %bb90, %bb88, %bb84, %bb83, %bb81, %bb77, %bb76, %bb74, %bb72, %bb68, %bb67, %bb65, %bb61, %bb60, %bb58, %bb54, %bb53, %bb51, %bb47, %bb46, %bb44, %bb42, %bb38, %bb37, %bb33, %bb32, %bb30, %bb26, %bb24, %bb22, %bb21, %bb17, %bb16, %bb12, %bb10, %bb8, %bb7, %bb5, %bb3, %bb1 - br i1 false, label %bb108, label %bb110 - -bb108: ; preds = %bb106, %picosat_time_stamp.exit - br i1 false, label %bb, label %bb110 - -bb110: ; preds = %bb108, %bb106 - br i1 false, label %bb112, label %bb171 - -bb112: ; preds = %bb110 - br i1 false, label %bb114, label %bb113 - -bb113: ; preds = %bb112 - br label %bb114 - -bb114: ; preds = %bb113, %bb112 - br i1 false, label %bb.i.i35, label %bb1.i.i36 - -bb.i.i35: ; preds = %bb114 - unreachable - -bb1.i.i36: ; preds = %bb114 - br i1 false, label %bb5.i.i.i41, label %bb6.i.i.i42 - -bb5.i.i.i41: ; preds = %bb1.i.i36 - unreachable - -bb6.i.i.i42: ; preds = %bb1.i.i36 - br i1 false, label %bb7.i.i.i43, label %bb8.i.i.i44 - -bb7.i.i.i43: ; preds = %bb6.i.i.i42 - br label %bb8.i.i.i44 - -bb8.i.i.i44: ; preds = %bb7.i.i.i43, %bb6.i.i.i42 - br i1 false, label %picosat_init.exit, label %bb14.i.i - -bb14.i.i: ; preds = %bb8.i.i.i44 - br label %picosat_init.exit - -picosat_init.exit: ; preds = %bb14.i.i, %bb8.i.i.i44 - br i1 false, label %bb116, label %bb115 - -bb115: ; preds = %picosat_init.exit - br label %bb116 - -bb116: ; preds = %bb115, %picosat_init.exit - br i1 false, label %bb119, label %bb118 - -bb118: ; preds = %bb116 - br label %bb119 - -bb119: ; preds = %bb118, %bb116 - br i1 false, label %bb121, label %bb120 - -bb120: ; preds = %bb119 - br label %bb121 - -bb121: ; preds = %bb120, %bb119 - br i1 false, label %bb126, label %bb122 - -bb122: ; preds = %bb121 - br label %bb126 - -bb126: ; preds = %bb122, %bb121 - br i1 false, label %bb128, label %bb127 - -bb127: ; preds = %bb126 - br label %bb128 - -bb128: ; preds = %bb127, %bb126 - br label %SKIP_COMMENTS.i - -SKIP_COMMENTS.i.loopexit: ; preds = %bb.i149, %bb.i149 - br label %SKIP_COMMENTS.i.backedge - -SKIP_COMMENTS.i: ; preds = %SKIP_COMMENTS.i.backedge, %bb128 - br i1 false, label %bb.i149.preheader, label %bb3.i152 - -bb.i149.preheader: ; preds = %SKIP_COMMENTS.i - br label %bb.i149 - -bb.i149: ; preds = %bb.i149, %bb.i149.preheader - switch i32 0, label %bb.i149 [ - i32 -1, label %SKIP_COMMENTS.i.loopexit - i32 10, label %SKIP_COMMENTS.i.loopexit - ] - -bb3.i152: ; preds = %SKIP_COMMENTS.i - br i1 false, label %bb4.i153, label %SKIP_COMMENTS.i.backedge - -SKIP_COMMENTS.i.backedge: ; preds = %bb3.i152, %SKIP_COMMENTS.i.loopexit - br label %SKIP_COMMENTS.i - -bb4.i153: ; preds = %bb3.i152 - br i1 false, label %bb5.i154, label %bb129 - -bb5.i154: ; preds = %bb4.i153 - br i1 false, label %bb129, label %bb6.i155.preheader - -bb6.i155.preheader: ; preds = %bb5.i154 - br label %bb6.i155 - -bb6.i155: ; preds = %bb6.i155, %bb6.i155.preheader - br i1 false, label %bb7.i156, label %bb6.i155 - -bb7.i156: ; preds = %bb6.i155 - br i1 false, label %bb8.i157, label %bb129 - -bb8.i157: ; preds = %bb7.i156 - br i1 false, label %bb9.i158, label %bb129 - -bb9.i158: ; preds = %bb8.i157 - br i1 false, label %bb10.i159, label %bb129 - -bb10.i159: ; preds = %bb9.i158 - br i1 false, label %bb129, label %bb11.i160.preheader - -bb11.i160.preheader: ; preds = %bb10.i159 - br label %bb11.i160 - -bb11.i160: ; preds = %bb11.i160, %bb11.i160.preheader - br i1 false, label %bb12.i161, label %bb11.i160 - -bb12.i161: ; preds = %bb11.i160 - br i1 false, label %bb129, label %bb15.i165.preheader - -bb15.i165.preheader: ; preds = %bb12.i161 - br label %bb15.i165 - -bb14.i163: ; preds = %bb15.i165 - br label %bb15.i165 - -bb15.i165: ; preds = %bb14.i163, %bb15.i165.preheader - br i1 false, label %bb16.i166, label %bb14.i163 - -bb16.i166: ; preds = %bb15.i165 - br i1 false, label %bb129, label %bb17.i167.preheader - -bb17.i167.preheader: ; preds = %bb16.i166 - br label %bb17.i167 - -bb17.i167: ; preds = %bb17.i167, %bb17.i167.preheader - br i1 false, label %bb18.i168, label %bb17.i167 - -bb18.i168: ; preds = %bb17.i167 - br i1 false, label %bb129, label %bb21.i172.preheader - -bb21.i172.preheader: ; preds = %bb18.i168 - br label %bb21.i172 - -bb20.i170: ; preds = %bb21.i172 - br label %bb21.i172 - -bb21.i172: ; preds = %bb20.i170, %bb21.i172.preheader - br i1 false, label %bb22.i173, label %bb20.i170 - -bb22.i173: ; preds = %bb21.i172 - br i1 false, label %bb24.i175, label %bb129 - -bb24.i175: ; preds = %bb22.i173 - br i1 false, label %bb26.i180, label %bb25.i176 - -bb25.i176: ; preds = %bb24.i175 - br label %bb26.i180 - -bb26.i180: ; preds = %bb25.i176, %bb24.i175 - br i1 false, label %bb.i.i181, label %bb3.i.i184.preheader - -bb.i.i181: ; preds = %bb26.i180 - br label %bb3.i.i184.preheader - -bb3.i.i184.preheader: ; preds = %bb.i.i181, %bb26.i180 - br label %bb3.i.i184 - -bb2.i.i183: ; preds = %bb3.i.i184 - br label %bb3.i.i184 - -bb3.i.i184: ; preds = %bb2.i.i183, %bb3.i.i184.preheader - br i1 false, label %bb2.i.i183, label %bb4.i.i185 - -bb4.i.i185: ; preds = %bb3.i.i184 - br i1 false, label %bb.i.i.i186, label %picosat_adjust.exit.i - -bb.i.i.i186: ; preds = %bb4.i.i185 - br label %picosat_adjust.exit.i - -picosat_adjust.exit.i: ; preds = %bb.i.i.i186, %bb4.i.i185 - br i1 false, label %bb28.i188, label %bb27.i187 - -bb27.i187: ; preds = %picosat_adjust.exit.i - br label %bb28.i188 - -bb28.i188: ; preds = %bb27.i187, %picosat_adjust.exit.i - br label %READ_LITERAL.i.outer - -READ_LITERAL.i.outer: ; preds = %READ_LITERAL.i.outer.backedge, %bb28.i188 - br label %READ_LITERAL.i - -READ_LITERAL.i.loopexit: ; preds = %bb29.i189, %bb29.i189 - br label %READ_LITERAL.i.backedge - -READ_LITERAL.i: ; preds = %READ_LITERAL.i.backedge, %READ_LITERAL.i.outer - switch i32 0, label %bb39.i199 [ - i32 99, label %bb29.i189.preheader - i32 -1, label %bb33.i193 - ] - -bb29.i189.preheader: ; preds = %READ_LITERAL.i - br label %bb29.i189 - -bb29.i189: ; preds = %bb29.i189, %bb29.i189.preheader - switch i32 0, label %bb29.i189 [ - i32 -1, label %READ_LITERAL.i.loopexit - i32 10, label %READ_LITERAL.i.loopexit - ] - -bb33.i193: ; preds = %READ_LITERAL.i - br i1 false, label %bb35.i195, label %parse.exit - -bb35.i195: ; preds = %bb33.i193 - br i1 false, label %bb38.i198, label %parse.exit - -bb38.i198: ; preds = %bb35.i195 - br label %parse.exit - -bb39.i199: ; preds = %READ_LITERAL.i - br i1 false, label %bb40.i200, label %READ_LITERAL.i.backedge - -READ_LITERAL.i.backedge: ; preds = %bb39.i199, %READ_LITERAL.i.loopexit - br label %READ_LITERAL.i - -bb40.i200: ; preds = %bb39.i199 - br i1 false, label %bb41.i201, label %bb42.i202 - -bb41.i201: ; preds = %bb40.i200 - br label %bb42.i202 - -bb42.i202: ; preds = %bb41.i201, %bb40.i200 - br i1 false, label %parse.exit.loopexit, label %bb46.i.preheader - -bb46.i.preheader: ; preds = %bb42.i202 - br label %bb46.i - -bb45.i: ; preds = %bb46.i - br label %bb46.i - -bb46.i: ; preds = %bb45.i, %bb46.i.preheader - br i1 false, label %bb47.i, label %bb45.i - -bb47.i: ; preds = %bb46.i - br i1 false, label %parse.exit.loopexit, label %bb50.i - -bb50.i: ; preds = %bb47.i - br i1 false, label %bb55.i, label %bb51.i - -bb51.i: ; preds = %bb50.i - br i1 false, label %parse.exit.loopexit, label %bb54.i - -bb54.i: ; preds = %bb51.i - br label %bb56.i - -bb55.i: ; preds = %bb50.i - br label %bb56.i - -bb56.i: ; preds = %bb55.i, %bb54.i - br i1 false, label %bb3.i11.i, label %bb.i8.i - -bb.i8.i: ; preds = %bb56.i - br i1 false, label %bb1.i9.i, label %bb3.i11.i - -bb1.i9.i: ; preds = %bb.i8.i - br i1 false, label %bb3.i11.i, label %bb2.i10.i - -bb2.i10.i: ; preds = %bb1.i9.i - unreachable - -bb3.i11.i: ; preds = %bb1.i9.i, %bb.i8.i, %bb56.i - br i1 false, label %bb7.i.i208, label %bb6.i.i207 - -bb6.i.i207: ; preds = %bb3.i11.i - br label %READ_LITERAL.i.outer.backedge - -bb7.i.i208: ; preds = %bb3.i11.i - br i1 false, label %bb53.i.i.i.i.preheader, label %bb.i.i.i.i210.preheader - -bb.i.i.i.i210.preheader: ; preds = %bb7.i.i208 - br label %bb.i.i.i.i210 - -bb.i.i.i.i210: ; preds = %bb.i.i.i.i210.backedge, %bb.i.i.i.i210.preheader - br i1 false, label %bb17.i.i.i.i, label %bb18.i.i.i.i - -bb17.i.i.i.i: ; preds = %bb.i.i.i.i210 - br label %bb18.i.i.i.i - -bb18.i.i.i.i: ; preds = %bb17.i.i.i.i, %bb.i.i.i.i210 - br i1 false, label %bb19.i.i.i.i, label %bb20.i.i.i.i - -bb19.i.i.i.i: ; preds = %bb18.i.i.i.i - br label %bb20.i.i.i.i - -bb20.i.i.i.i: ; preds = %bb19.i.i.i.i, %bb18.i.i.i.i - br i1 false, label %bb21.i.i.i.i, label %bb22.i.i.i.i - -bb21.i.i.i.i: ; preds = %bb20.i.i.i.i - br label %bb22.i.i.i.i - -bb22.i.i.i.i: ; preds = %bb21.i.i.i.i, %bb20.i.i.i.i - br label %bb23.i.i.i.i.outer - -bb23.i.i.i.i.outer: ; preds = %bb28.i.i.i.i, %bb22.i.i.i.i - br label %bb23.i.i.i.i - -bb23.i.i.i.i: ; preds = %bb23.i.i.i.i, %bb23.i.i.i.i.outer - br i1 false, label %bb23.i.i.i.i, label %bb26.i.i.i.i.preheader - -bb26.i.i.i.i.preheader: ; preds = %bb23.i.i.i.i - br label %bb26.i.i.i.i - -bb26.i.i.i.i: ; preds = %bb26.i.i.i.i, %bb26.i.i.i.i.preheader - br i1 false, label %bb27.i.i.i.i, label %bb26.i.i.i.i - -bb27.i.i.i.i: ; preds = %bb26.i.i.i.i - br i1 false, label %bb28.i.i.i.i, label %bb29.i.i.i.i - -bb28.i.i.i.i: ; preds = %bb27.i.i.i.i - br label %bb23.i.i.i.i.outer - -bb29.i.i.i.i: ; preds = %bb27.i.i.i.i - br i1 false, label %bb33.i.i.i.i, label %bb44.i.i.i.i - -bb33.i.i.i.i: ; preds = %bb29.i.i.i.i - br i1 false, label %bb34.i.i.i.i, label %bb38.i.i.i.i - -bb34.i.i.i.i: ; preds = %bb33.i.i.i.i - br i1 false, label %bb37.i.i.i.i, label %bb35.i.i.i.i - -bb35.i.i.i.i: ; preds = %bb34.i.i.i.i - br label %bb37.i.i.i.i - -bb37.i.i.i.i: ; preds = %bb35.i.i.i.i, %bb34.i.i.i.i - br label %bb38.i.i.i.i - -bb38.i.i.i.i: ; preds = %bb37.i.i.i.i, %bb33.i.i.i.i - br i1 false, label %bb39.i.i.i.i, label %bb43.i.i.i.i - -bb39.i.i.i.i: ; preds = %bb38.i.i.i.i - br i1 false, label %bb42.i.i.i.i, label %bb40.i.i.i.i - -bb40.i.i.i.i: ; preds = %bb39.i.i.i.i - br label %bb42.i.i.i.i - -bb42.i.i.i.i: ; preds = %bb40.i.i.i.i, %bb39.i.i.i.i - br label %bb43.i.i.i.i - -bb43.i.i.i.i: ; preds = %bb42.i.i.i.i, %bb38.i.i.i.i - br label %bb.i.i.i.i210.backedge - -bb.i.i.i.i210.backedge: ; preds = %bb47.i.i.i.i, %bb44.i.i.i.i, %bb43.i.i.i.i - br label %bb.i.i.i.i210 - -bb44.i.i.i.i: ; preds = %bb29.i.i.i.i - br i1 false, label %bb.i.i.i.i210.backedge, label %bb46.i.i.i.i - -bb46.i.i.i.i: ; preds = %bb44.i.i.i.i - br i1 false, label %bb47.i.i.i.i, label %bb53.i.i.i.i.preheader.loopexit - -bb53.i.i.i.i.preheader.loopexit: ; preds = %bb46.i.i.i.i - br label %bb53.i.i.i.i.preheader - -bb53.i.i.i.i.preheader: ; preds = %bb53.i.i.i.i.preheader.loopexit, %bb7.i.i208 - br label %bb53.i.i.i.i - -bb47.i.i.i.i: ; preds = %bb46.i.i.i.i - br label %bb.i.i.i.i210.backedge - -bb50.i.i.i.i: ; preds = %bb53.i.i.i.i - br i1 false, label %bb51.i.i.i.i, label %bb52.i.i.i.i - -bb51.i.i.i.i: ; preds = %bb50.i.i.i.i - br label %bb52.i.i.i.i - -bb52.i.i.i.i: ; preds = %bb51.i.i.i.i, %bb50.i.i.i.i - br label %bb53.i.i.i.i - -bb53.i.i.i.i: ; preds = %bb52.i.i.i.i, %bb53.i.i.i.i.preheader - br i1 false, label %bb50.i.i.i.i, label %bb59.i.i.i.i.preheader - -bb59.i.i.i.i.preheader: ; preds = %bb53.i.i.i.i - br label %bb59.i.i.i.i - -bb55.i.i.i.i: ; preds = %bb59.i.i.i.i - br label %bb57.i.i.i.i - -bb56.i.i.i.i: ; preds = %bb57.i.i.i.i - br label %bb57.i.i.i.i - -bb57.i.i.i.i: ; preds = %bb56.i.i.i.i, %bb55.i.i.i.i - br i1 false, label %bb56.i.i.i.i, label %bb58.i.i.i.i - -bb58.i.i.i.i: ; preds = %bb57.i.i.i.i - br label %bb59.i.i.i.i - -bb59.i.i.i.i: ; preds = %bb58.i.i.i.i, %bb59.i.i.i.i.preheader - br i1 false, label %bb60.i.i.i.i, label %bb55.i.i.i.i - -bb60.i.i.i.i: ; preds = %bb59.i.i.i.i - br label %bb69.i.i.i.i - -bb61.i.i.i.i: ; preds = %bb69.i.i.i.i - br i1 false, label %bb68.i.i.i.i, label %bb62.i.i.i.i - -bb62.i.i.i.i: ; preds = %bb61.i.i.i.i - br i1 false, label %bb63.i.i.i.i, label %bb65.i.i.i.i - -bb63.i.i.i.i: ; preds = %bb62.i.i.i.i - br i1 false, label %bb.i.i12.i, label %bb65.i.i.i.i - -bb65.i.i.i.i: ; preds = %bb63.i.i.i.i, %bb62.i.i.i.i - br i1 false, label %bb.i.i12.i, label %bb67.i.i.i.i - -bb67.i.i.i.i: ; preds = %bb65.i.i.i.i - br label %bb68.i.i.i.i - -bb68.i.i.i.i: ; preds = %bb67.i.i.i.i, %bb61.i.i.i.i - br label %bb69.i.i.i.i - -bb69.i.i.i.i: ; preds = %bb68.i.i.i.i, %bb60.i.i.i.i - br i1 false, label %bb61.i.i.i.i, label %bb70.i.i.i.i - -bb70.i.i.i.i: ; preds = %bb69.i.i.i.i - br label %READ_LITERAL.i.outer.backedge - -bb.i.i12.i: ; preds = %bb65.i.i.i.i, %bb63.i.i.i.i - br i1 false, label %bb1.i.i.i213, label %bb5.i.i.i218 - -bb1.i.i.i213: ; preds = %bb.i.i12.i - br i1 false, label %bb4.i.i.i217, label %bb2.i.i.i214 - -bb2.i.i.i214: ; preds = %bb1.i.i.i213 - br label %bb4.i.i.i217 - -bb4.i.i.i217: ; preds = %bb2.i.i.i214, %bb1.i.i.i213 - br label %bb5.i.i.i218 - -bb5.i.i.i218: ; preds = %bb4.i.i.i217, %bb.i.i12.i - br label %READ_LITERAL.i.outer.backedge - -READ_LITERAL.i.outer.backedge: ; preds = %bb5.i.i.i218, %bb70.i.i.i.i, %bb6.i.i207 - br label %READ_LITERAL.i.outer - -parse.exit.loopexit: ; preds = %bb51.i, %bb47.i, %bb42.i202 - br label %parse.exit - -parse.exit: ; preds = %parse.exit.loopexit, %bb38.i198, %bb35.i195, %bb33.i193 - br i1 false, label %bb130, label %bb129 - -bb129: ; preds = %parse.exit, %bb22.i173, %bb18.i168, %bb16.i166, %bb12.i161, %bb10.i159, %bb9.i158, %bb8.i157, %bb7.i156, %bb5.i154, %bb4.i153 - br label %bb170 - -bb130: ; preds = %parse.exit - br i1 false, label %bb143, label %bb142.preheader - -bb142.preheader: ; preds = %bb130 - br label %bb142 - -bb132: ; preds = %bb142 - br i1 false, label %bb137, label %bb133 - -bb133: ; preds = %bb132 - br i1 false, label %bb137, label %bb134 - -bb134: ; preds = %bb133 - br i1 false, label %bb137, label %bb135 - -bb135: ; preds = %bb134 - br i1 false, label %bb137, label %bb136 - -bb136: ; preds = %bb135 - br i1 false, label %bb137, label %bb138 - -bb137: ; preds = %bb136, %bb135, %bb134, %bb133, %bb132 - br label %bb141 - -bb138: ; preds = %bb136 - br i1 false, label %bb139, label %bb141 - -bb139: ; preds = %bb138 - br i1 false, label %bb2.i126, label %picosat_assume.exit - -bb2.i126: ; preds = %bb139 - br i1 false, label %bb5.i130, label %bb3.i127 - -bb3.i127: ; preds = %bb2.i126 - br label %bb5.i130 - -bb5.i130: ; preds = %bb3.i127, %bb2.i126 - br label %picosat_assume.exit - -picosat_assume.exit: ; preds = %bb5.i130, %bb139 - br i1 false, label %bb141, label %bb140 - -bb140: ; preds = %picosat_assume.exit - br label %bb141 - -bb141: ; preds = %bb140, %picosat_assume.exit, %bb138, %bb137 - br label %bb142 - -bb142: ; preds = %bb141, %bb142.preheader - br i1 false, label %bb132, label %bb143.loopexit - -bb143.loopexit: ; preds = %bb142 - br label %bb143 - -bb143: ; preds = %bb143.loopexit, %bb130 - br i1 false, label %bb145, label %bb144 - -bb144: ; preds = %bb143 - br label %bb11.i - -bb5.i114: ; preds = %bb11.i - br label %bb11.i - -bb11.i: ; preds = %bb5.i114, %bb144 - br i1 false, label %bb12.i, label %bb5.i114 - -bb12.i: ; preds = %bb11.i - br i1 false, label %bb.i.i.i118, label %bb1.i.i.i119 - -bb.i.i.i118: ; preds = %bb12.i - br label %int2lit.exit.i - -bb1.i.i.i119: ; preds = %bb12.i - br label %int2lit.exit.i - -int2lit.exit.i: ; preds = %bb1.i.i.i119, %bb.i.i.i118 - br label %bb19.i - -bb13.i: ; preds = %bb19.i - br label %bb17.i - -bb14.i: ; preds = %bb17.i - br label %bb17.i - -bb17.i: ; preds = %bb14.i, %bb13.i - br i1 false, label %bb14.i, label %bb18.i - -bb18.i: ; preds = %bb17.i - br label %bb19.i - -bb19.i: ; preds = %bb18.i, %int2lit.exit.i - br i1 false, label %bb20.i, label %bb13.i - -bb20.i: ; preds = %bb19.i - br label %bb33.i - -bb24.i: ; preds = %bb33.i - br i1 false, label %bb29.i, label %bb25.i - -bb25.i: ; preds = %bb24.i - br label %bb27.i - -bb26.i: ; preds = %bb27.i - br label %bb27.i - -bb27.i: ; preds = %bb26.i, %bb25.i - br i1 false, label %bb26.i, label %bb28.i - -bb28.i: ; preds = %bb27.i - br label %bb29.i - -bb29.i: ; preds = %bb28.i, %bb24.i - br label %bb33.i - -bb33.i: ; preds = %bb29.i, %bb20.i - br i1 false, label %bb34.i, label %bb24.i - -bb34.i: ; preds = %bb33.i - br i1 false, label %bb.i.i58.i, label %bb1.i.i59.i - -bb.i.i58.i: ; preds = %bb34.i - br label %int2lit.exit63.i - -bb1.i.i59.i: ; preds = %bb34.i - br label %int2lit.exit63.i - -int2lit.exit63.i: ; preds = %bb1.i.i59.i, %bb.i.i58.i - br label %bb41.i - -bb35.i: ; preds = %bb41.i - br label %bb39.i - -bb36.i: ; preds = %bb39.i - br i1 false, label %bb38.i, label %bb37.i - -bb37.i: ; preds = %bb36.i - br label %bb38.i - -bb38.i: ; preds = %bb37.i, %bb36.i - br label %bb39.i - -bb39.i: ; preds = %bb38.i, %bb35.i - br i1 false, label %bb36.i, label %bb40.i - -bb40.i: ; preds = %bb39.i - br label %bb41.i - -bb41.i: ; preds = %bb40.i, %int2lit.exit63.i - br i1 false, label %bb42.i, label %bb35.i - -bb42.i: ; preds = %bb41.i - br label %bb44.i - -bb43.i: ; preds = %bb44.i - br label %bb44.i - -bb44.i: ; preds = %bb43.i, %bb42.i - br i1 false, label %bb43.i, label %picosat_print.exit - -picosat_print.exit: ; preds = %bb44.i - br label %bb167 - -bb145: ; preds = %bb143 - br i1 false, label %bb147, label %bb146 - -bb146: ; preds = %bb145 - br label %bb147 - -bb147: ; preds = %bb146, %bb145 - br i1 false, label %bb149, label %bb148 - -bb148: ; preds = %bb147 - br label %bb149 - -bb149: ; preds = %bb148, %bb147 - br i1 false, label %bb.i54, label %bb1.i55 - -bb.i54: ; preds = %bb149 - unreachable - -bb1.i55: ; preds = %bb149 - br i1 false, label %bb.i.i56, label %bb1.i.i57 - -bb.i.i56: ; preds = %bb1.i55 - br label %bb1.i.i57 - -bb1.i.i57: ; preds = %bb.i.i56, %bb1.i55 - br i1 false, label %bb3.i.i59, label %bb2.i.i58 - -bb2.i.i58: ; preds = %bb1.i.i57 - br label %bb3.i.i59 - -bb3.i.i59: ; preds = %bb2.i.i58, %bb1.i.i57 - br i1 false, label %bb5.i.i61, label %sat.exit.i - -bb5.i.i61: ; preds = %bb3.i.i59 - br i1 false, label %bb6.i.i65, label %bb1.i.i.i63 - -bb1.i.i.i63: ; preds = %bb5.i.i61 - br i1 false, label %sat.exit.i, label %bb6.i.i65 - -bb6.i.i65: ; preds = %bb1.i.i.i63, %bb5.i.i61 - br i1 false, label %bb8.i.i67, label %bb7.i.i66 - -bb7.i.i66: ; preds = %bb6.i.i65 - br label %bb8.i.i67 - -bb8.i.i67: ; preds = %bb7.i.i66, %bb6.i.i65 - br i1 false, label %bb10.i.i69, label %sat.exit.i - -bb10.i.i69: ; preds = %bb8.i.i67 - br i1 false, label %bb11.i.i70, label %bb1.i61.i.i - -bb1.i61.i.i: ; preds = %bb10.i.i69 - br i1 false, label %sat.exit.i, label %bb11.i.i70 - -bb11.i.i70: ; preds = %bb1.i61.i.i, %bb10.i.i69 - br label %bb13.i.i71.outer - -bb13.i.i71.outer: ; preds = %bb42.i.i, %bb11.i.i70 - br label %bb13.i.i71 - -bb13.i.i71: ; preds = %bb13.i.i71.backedge, %bb13.i.i71.outer - br i1 false, label %bb14.i.i72, label %bb15.i.i73 - -bb14.i.i72: ; preds = %bb13.i.i71 - br label %bb15.i.i73 - -bb15.i.i73: ; preds = %bb14.i.i72, %bb13.i.i71 - br i1 false, label %bb19.i.i, label %bb16.i.i - -bb16.i.i: ; preds = %bb15.i.i73 - br i1 false, label %bb.i.i79.i.i, label %incincs.exit.i.i - -bb.i.i79.i.i: ; preds = %bb16.i.i - br label %bb4.i.i.i85.i.i - -bb.i.i.i80.i.i: ; preds = %bb4.i.i.i85.i.i - br i1 false, label %bb3.i.i.i83.i.i, label %bb1.i.i.i81.i.i - -bb1.i.i.i81.i.i: ; preds = %bb.i.i.i80.i.i - br i1 false, label %bb2.i.i.i82.i.i, label %bb3.i.i.i83.i.i - -bb2.i.i.i82.i.i: ; preds = %bb1.i.i.i81.i.i - br label %bb3.i.i.i83.i.i - -bb3.i.i.i83.i.i: ; preds = %bb2.i.i.i82.i.i, %bb1.i.i.i81.i.i, %bb.i.i.i80.i.i - br label %bb4.i.i.i85.i.i - -bb4.i.i.i85.i.i: ; preds = %bb3.i.i.i83.i.i, %bb.i.i79.i.i - br i1 false, label %crescore.exit.i.i.i.i, label %bb.i.i.i80.i.i - -crescore.exit.i.i.i.i: ; preds = %bb4.i.i.i85.i.i - br label %incincs.exit.i.i - -incincs.exit.i.i: ; preds = %crescore.exit.i.i.i.i, %bb16.i.i - br i1 false, label %bb13.i.i71.backedge, label %sat.exit.i.loopexit.loopexit - -bb13.i.i71.backedge: ; preds = %bb1.i55.i.i, %bb28.i.i, %incincs.exit.i.i - br label %bb13.i.i71 - -bb19.i.i: ; preds = %bb15.i.i73 - br i1 false, label %bb20.i.i, label %bb1.i68.i.i - -bb1.i68.i.i: ; preds = %bb19.i.i - br i1 false, label %sat.exit.i.loopexit.loopexit, label %bb20.i.i - -bb20.i.i: ; preds = %bb1.i68.i.i, %bb19.i.i - br i1 false, label %bb24.i.i, label %bb21.i.i - -bb21.i.i: ; preds = %bb20.i.i - br i1 false, label %bb22.i.i, label %bb24.i.i - -bb22.i.i: ; preds = %bb21.i.i - br i1 false, label %bb23.i.i, label %bb24.i.i - -bb23.i.i: ; preds = %bb22.i.i - br label %bb24.i.i - -bb24.i.i: ; preds = %bb23.i.i, %bb22.i.i, %bb21.i.i, %bb20.i.i - br i1 false, label %bb26.i.i, label %sat.exit.i.loopexit.loopexit - -bb26.i.i: ; preds = %bb24.i.i - br i1 false, label %bb27.i.i, label %bb33.i.i.loopexit - -bb27.i.i: ; preds = %bb26.i.i - br i1 false, label %bb33.i.i.loopexit, label %bb28.i.i - -bb28.i.i: ; preds = %bb27.i.i - br i1 false, label %bb1.i55.i.i, label %bb13.i.i71.backedge - -bb1.i55.i.i: ; preds = %bb28.i.i - br i1 false, label %bb29.i.i, label %bb13.i.i71.backedge - -bb29.i.i: ; preds = %bb1.i55.i.i - br i1 false, label %bb31.i.i, label %sat.exit.i.loopexit.loopexit2 - -bb31.i.i: ; preds = %bb29.i.i - br i1 false, label %bb33.i.i, label %bb1.i48.i.i - -bb1.i48.i.i: ; preds = %bb31.i.i - br i1 false, label %sat.exit.i.loopexit.loopexit2, label %bb33.i.i - -bb33.i.i.loopexit: ; preds = %bb27.i.i, %bb26.i.i - br label %bb33.i.i - -bb33.i.i: ; preds = %bb33.i.i.loopexit, %bb1.i48.i.i, %bb31.i.i - br i1 false, label %bb34.i.i, label %bb35.i.i - -bb34.i.i: ; preds = %bb33.i.i - br i1 false, label %bb35.i.i, label %bb2.i44.i.i76 - -bb2.i44.i.i76: ; preds = %bb34.i.i - br label %bb35.i.i - -bb35.i.i: ; preds = %bb2.i44.i.i76, %bb34.i.i, %bb33.i.i - br i1 false, label %bb1.i37.i.i, label %bb.i35.i.i - -bb.i35.i.i: ; preds = %bb35.i.i - br label %bb36.i.i - -bb1.i37.i.i: ; preds = %bb35.i.i - br i1 false, label %bb37.i.i, label %bb36.i.i - -bb36.i.i: ; preds = %bb1.i37.i.i, %bb.i35.i.i - br label %bb25.i23.i.i - -bb.i18.i.i: ; preds = %bb25.i23.i.i - br i1 false, label %bb24.i22.i.i, label %bb22.i19.i.i - -bb22.i19.i.i: ; preds = %bb.i18.i.i - br label %bb24.i22.i.i - -bb24.i22.i.i: ; preds = %bb22.i19.i.i, %bb.i18.i.i - br label %bb25.i23.i.i - -bb25.i23.i.i: ; preds = %bb24.i22.i.i, %bb36.i.i - br i1 false, label %bb.i18.i.i, label %bb26.i24.i.i - -bb26.i24.i.i: ; preds = %bb25.i23.i.i - br i1 false, label %bb27.i25.i.i, label %bb32.i.i.i - -bb27.i25.i.i: ; preds = %bb26.i24.i.i - br label %bb32.i.i.i - -bb32.i.i.i: ; preds = %bb27.i25.i.i, %bb26.i24.i.i - br label %bb64.i.i.i - -bb33.i.i.i: ; preds = %bb64.i.i.i - br i1 false, label %bb60.i.i.i, label %bb34.i.i.i - -bb34.i.i.i: ; preds = %bb33.i.i.i - br i1 false, label %bb38.i.i.i, label %bb60.i.i.i - -bb38.i.i.i: ; preds = %bb34.i.i.i - br i1 false, label %bb39.i.i.i, label %bb48.i.i.i - -bb39.i.i.i: ; preds = %bb38.i.i.i - br i1 false, label %bb48.i.i.i, label %bb40.i.i.i - -bb40.i.i.i: ; preds = %bb39.i.i.i - br i1 false, label %bb60.i.i.i, label %bb45.i.i.i - -bb45.i.i.i: ; preds = %bb40.i.i.i - br label %bb60.i.i.i - -bb48.i.i.i: ; preds = %bb39.i.i.i, %bb38.i.i.i - br i1 false, label %bb53.i.i.i, label %bb60.i.i.i - -bb53.i.i.i: ; preds = %bb48.i.i.i - br i1 false, label %bb60.i.i.i, label %bb58.i.i.i - -bb58.i.i.i: ; preds = %bb53.i.i.i - br i1 false, label %bb59.i.i.i, label %bb60.i.i.i - -bb59.i.i.i: ; preds = %bb58.i.i.i - br label %bb60.i.i.i - -bb60.i.i.i: ; preds = %bb59.i.i.i, %bb58.i.i.i, %bb53.i.i.i, %bb48.i.i.i, %bb45.i.i.i, %bb40.i.i.i, %bb34.i.i.i, %bb33.i.i.i - %lcollect.i.i.i.1 = phi i32 [ %lcollect.i.i.i.2, %bb34.i.i.i ], [ %lcollect.i.i.i.2, %bb48.i.i.i ], [ %lcollect.i.i.i.2, %bb58.i.i.i ], [ %lcollect.i.i.i.2, %bb59.i.i.i ], [ %lcollect.i.i.i.2, %bb53.i.i.i ], [ %lcollect.i.i.i.2, %bb33.i.i.i ], [ %lcollect.i.i.i.2, %bb40.i.i.i ], [ 0, %bb45.i.i.i ] ; [#uses=1] - br label %bb64.i.i.i - -bb64.i.i.i: ; preds = %bb60.i.i.i, %bb32.i.i.i - %lcollect.i.i.i.2 = phi i32 [ 0, %bb32.i.i.i ], [ %lcollect.i.i.i.1, %bb60.i.i.i ] ; [#uses=8] - br i1 false, label %bb65.i.i.i, label %bb33.i.i.i - -bb65.i.i.i: ; preds = %bb64.i.i.i - br i1 false, label %bb103.i.i.i.preheader, label %bb66.i.i.i.preheader - -bb66.i.i.i.preheader: ; preds = %bb65.i.i.i - br label %bb66.i.i.i - -bb66.i.i.i: ; preds = %bb66.i.i.i.backedge, %bb66.i.i.i.preheader - br i1 false, label %bb67.i.i.i, label %bb68.i.i.i - -bb67.i.i.i: ; preds = %bb66.i.i.i - br label %bb68.i.i.i - -bb68.i.i.i: ; preds = %bb67.i.i.i, %bb66.i.i.i - br i1 false, label %bb69.i.i.i, label %bb70.i.i.i - -bb69.i.i.i: ; preds = %bb68.i.i.i - br label %bb70.i.i.i - -bb70.i.i.i: ; preds = %bb69.i.i.i, %bb68.i.i.i - br i1 false, label %bb71.i.i.i, label %bb72.i.i.i - -bb71.i.i.i: ; preds = %bb70.i.i.i - br label %bb72.i.i.i - -bb72.i.i.i: ; preds = %bb71.i.i.i, %bb70.i.i.i - br label %bb73.i.i.i.outer - -bb73.i.i.i.outer: ; preds = %bb78.i.i.i, %bb72.i.i.i - br label %bb73.i.i.i - -bb73.i.i.i: ; preds = %bb73.i.i.i, %bb73.i.i.i.outer - br i1 false, label %bb73.i.i.i, label %bb76.i.i.i.preheader - -bb76.i.i.i.preheader: ; preds = %bb73.i.i.i - br label %bb76.i.i.i - -bb76.i.i.i: ; preds = %bb76.i.i.i, %bb76.i.i.i.preheader - br i1 false, label %bb77.i.i.i, label %bb76.i.i.i - -bb77.i.i.i: ; preds = %bb76.i.i.i - br i1 false, label %bb78.i.i.i, label %bb79.i.i.i - -bb78.i.i.i: ; preds = %bb77.i.i.i - br label %bb73.i.i.i.outer - -bb79.i.i.i: ; preds = %bb77.i.i.i - br i1 false, label %bb83.i.i.i, label %bb94.i.i.i - -bb83.i.i.i: ; preds = %bb79.i.i.i - br i1 false, label %bb84.i.i.i, label %bb88.i.i.i - -bb84.i.i.i: ; preds = %bb83.i.i.i - br i1 false, label %bb87.i.i.i, label %bb85.i.i.i - -bb85.i.i.i: ; preds = %bb84.i.i.i - br label %bb87.i.i.i - -bb87.i.i.i: ; preds = %bb85.i.i.i, %bb84.i.i.i - br label %bb88.i.i.i - -bb88.i.i.i: ; preds = %bb87.i.i.i, %bb83.i.i.i - br i1 false, label %bb89.i.i.i, label %bb93.i.i.i - -bb89.i.i.i: ; preds = %bb88.i.i.i - br i1 false, label %bb92.i.i.i, label %bb90.i.i.i - -bb90.i.i.i: ; preds = %bb89.i.i.i - br label %bb92.i.i.i - -bb92.i.i.i: ; preds = %bb90.i.i.i, %bb89.i.i.i - br label %bb93.i.i.i - -bb93.i.i.i: ; preds = %bb92.i.i.i, %bb88.i.i.i - br label %bb66.i.i.i.backedge - -bb66.i.i.i.backedge: ; preds = %bb97.i.i.i, %bb94.i.i.i, %bb93.i.i.i - br label %bb66.i.i.i - -bb94.i.i.i: ; preds = %bb79.i.i.i - br i1 false, label %bb66.i.i.i.backedge, label %bb96.i.i.i - -bb96.i.i.i: ; preds = %bb94.i.i.i - br i1 false, label %bb97.i.i.i, label %bb103.i.i.i.preheader.loopexit - -bb103.i.i.i.preheader.loopexit: ; preds = %bb96.i.i.i - br label %bb103.i.i.i.preheader - -bb103.i.i.i.preheader: ; preds = %bb103.i.i.i.preheader.loopexit, %bb65.i.i.i - br label %bb103.i.i.i - -bb97.i.i.i: ; preds = %bb96.i.i.i - br label %bb66.i.i.i.backedge - -bb100.i.i.i: ; preds = %bb103.i.i.i - br i1 false, label %bb101.i.i.i, label %bb102.i.i.i - -bb101.i.i.i: ; preds = %bb100.i.i.i - br label %bb102.i.i.i - -bb102.i.i.i: ; preds = %bb101.i.i.i, %bb100.i.i.i - br label %bb103.i.i.i - -bb103.i.i.i: ; preds = %bb102.i.i.i, %bb103.i.i.i.preheader - br i1 false, label %bb100.i.i.i, label %bb109.i.i.i.preheader - -bb109.i.i.i.preheader: ; preds = %bb103.i.i.i - br label %bb109.i.i.i - -bb105.i.i.i: ; preds = %bb109.i.i.i - br label %bb107.i.i.i - -bb106.i.i.i: ; preds = %bb107.i.i.i - br label %bb107.i.i.i - -bb107.i.i.i: ; preds = %bb106.i.i.i, %bb105.i.i.i - br i1 false, label %bb106.i.i.i, label %bb108.i.i.i - -bb108.i.i.i: ; preds = %bb107.i.i.i - br label %bb109.i.i.i - -bb109.i.i.i: ; preds = %bb108.i.i.i, %bb109.i.i.i.preheader - br i1 false, label %bb110.i.i.i, label %bb105.i.i.i - -bb110.i.i.i: ; preds = %bb109.i.i.i - %0 = sub i32 0, %lcollect.i.i.i.2 ; [#uses=1] - %1 = add i32 %0, 1 ; [#uses=1] - br label %bb113.i.i.i - -bb111.i.i.i: ; preds = %bb113.i.i.i - br i1 false, label %bb114.i.i.i, label %bb113.i.i.i - -bb113.i.i.i: ; preds = %bb111.i.i.i, %bb110.i.i.i - br i1 false, label %bb111.i.i.i, label %bb114.i.i.i - -bb114.i.i.i: ; preds = %bb113.i.i.i, %bb111.i.i.i - %2 = lshr i32 %1, 1 ; [#uses=2] - br i1 false, label %bb116.i.i.i, label %bb124.i.i.i - -bb116.i.i.i: ; preds = %bb114.i.i.i - br i1 false, label %bb117.i.i.i.preheader, label %bb122.i.i.i.preheader - -bb122.i.i.i.preheader: ; preds = %bb116.i.i.i - br label %bb122.i.i.i - -bb117.i.i.i.preheader: ; preds = %bb116.i.i.i - br label %bb117.i.i.i - -bb117.i.i.i: ; preds = %bb118.i.i.i, %bb117.i.i.i.preheader - %target.i.i.i.1 = phi i32 [ %3, %bb118.i.i.i ], [ %2, %bb117.i.i.i.preheader ] ; [#uses=1] - %3 = add i32 %target.i.i.i.1, 1 ; [#uses=2] - br i1 false, label %bb118.i.i.i, label %bb124.i.i.i.loopexit - -bb118.i.i.i: ; preds = %bb117.i.i.i - br i1 false, label %bb117.i.i.i, label %bb124.i.i.i.loopexit - -bb122.i.i.i: ; preds = %bb123.i.i.i, %bb122.i.i.i.preheader - %target.i.i.i.2 = phi i32 [ %4, %bb123.i.i.i ], [ %2, %bb122.i.i.i.preheader ] ; [#uses=2] - br i1 false, label %bb124.i.i.i.loopexit1, label %bb123.i.i.i - -bb123.i.i.i: ; preds = %bb122.i.i.i - %4 = add i32 %target.i.i.i.2, -1 ; [#uses=1] - br i1 false, label %bb122.i.i.i, label %bb124.i.i.i.loopexit1 - -bb124.i.i.i.loopexit: ; preds = %bb118.i.i.i, %bb117.i.i.i - br label %bb124.i.i.i - -bb124.i.i.i.loopexit1: ; preds = %bb123.i.i.i, %bb122.i.i.i - br label %bb124.i.i.i - -bb124.i.i.i: ; preds = %bb124.i.i.i.loopexit1, %bb124.i.i.i.loopexit, %bb114.i.i.i - %target.i.i.i.0 = phi i32 [ 0, %bb114.i.i.i ], [ %3, %bb124.i.i.i.loopexit ], [ %target.i.i.i.2, %bb124.i.i.i.loopexit1 ] ; [#uses=0] - br label %bb132.i.i.i.outer - -bb125.i.i.i: ; preds = %bb132.i.i.i - br i1 false, label %bb132.i.i.i, label %bb130.i.i.i - -bb130.i.i.i: ; preds = %bb125.i.i.i - br label %bb132.i.i.i.outer - -bb132.i.i.i.outer: ; preds = %bb130.i.i.i, %bb124.i.i.i - br label %bb132.i.i.i - -bb132.i.i.i: ; preds = %bb132.i.i.i.outer, %bb125.i.i.i - br i1 false, label %bb125.i.i.i, label %bb133.i.i.i - -bb133.i.i.i: ; preds = %bb132.i.i.i - br i1 false, label %bb136.i.i.i, label %bb134.i.i.i - -bb134.i.i.i: ; preds = %bb133.i.i.i - br i1 false, label %bb136.i.i.i, label %bb135.i.i.i - -bb135.i.i.i: ; preds = %bb134.i.i.i - br label %bb136.i.i.i - -bb136.i.i.i: ; preds = %bb135.i.i.i, %bb134.i.i.i, %bb133.i.i.i - br i1 false, label %bb137.i.i.i, label %bb37.i.i - -bb137.i.i.i: ; preds = %bb136.i.i.i - br label %bb37.i.i - -bb37.i.i: ; preds = %bb137.i.i.i, %bb136.i.i.i, %bb1.i37.i.i - br i1 false, label %bb40.i.i, label %bb38.i.i - -bb38.i.i: ; preds = %bb37.i.i - br i1 false, label %bb39.i.i, label %bb40.i.i - -bb39.i.i: ; preds = %bb38.i.i - br i1 false, label %bb17.i.i.i, label %bb3.i12.i.i - -bb3.i12.i.i: ; preds = %bb39.i.i - br label %bb5.i14.i.i - -bb5.i14.i.i: ; preds = %bb8.i.i.i79, %bb3.i12.i.i - br i1 false, label %bb6.i15.i.i, label %bb9.i.i.i80 - -bb6.i15.i.i: ; preds = %bb5.i14.i.i - br i1 false, label %bb7.i.i.i78, label %bb9.i.i.i80 - -bb7.i.i.i78: ; preds = %bb6.i15.i.i - br i1 false, label %bb9.i.i.i80, label %bb8.i.i.i79 - -bb8.i.i.i79: ; preds = %bb7.i.i.i78 - br i1 false, label %bb9.i.i.i80, label %bb5.i14.i.i - -bb9.i.i.i80: ; preds = %bb8.i.i.i79, %bb7.i.i.i78, %bb6.i15.i.i, %bb5.i14.i.i - br i1 false, label %bb16.i.i.i, label %bb10.i.i.i81 - -bb10.i.i.i81: ; preds = %bb9.i.i.i80 - br i1 false, label %bb11.i.i.i, label %bb15.i.i.i - -bb11.i.i.i: ; preds = %bb10.i.i.i81 - br i1 false, label %bb16.i.i.i, label %bb15.i.i.i - -bb15.i.i.i: ; preds = %bb11.i.i.i, %bb10.i.i.i81 - br label %bb16.i.i.i - -bb16.i.i.i: ; preds = %bb15.i.i.i, %bb11.i.i.i, %bb9.i.i.i80 - br label %bb17.i.i.i - -bb17.i.i.i: ; preds = %bb16.i.i.i, %bb39.i.i - br i1 false, label %bb18.i.i.i, label %bb25.i.i.i - -bb18.i.i.i: ; preds = %bb17.i.i.i - br i1 false, label %bb24.i.i.i, label %bb23.i.i.i - -bb23.i.i.i: ; preds = %bb18.i.i.i - br label %bb24.i.i.i - -bb24.i.i.i: ; preds = %bb23.i.i.i, %bb18.i.i.i - br label %bb29.i.i.i - -bb25.i.i.i: ; preds = %bb17.i.i.i - br i1 false, label %bb29.i.i.i, label %bb27.i.i.i - -bb27.i.i.i: ; preds = %bb25.i.i.i - br i1 false, label %bb29.i.i.i, label %bb28.i.i.i - -bb28.i.i.i: ; preds = %bb27.i.i.i - br i1 false, label %bb29.i.i.i, label %bb.i4.i.i.i - -bb.i4.i.i.i: ; preds = %bb28.i.i.i - br i1 false, label %bb4.i.i16.i.i, label %bb29.i.i.i - -bb4.i.i16.i.i: ; preds = %bb.i4.i.i.i - br label %bb29.i.i.i - -bb29.i.i.i: ; preds = %bb4.i.i16.i.i, %bb.i4.i.i.i, %bb28.i.i.i, %bb27.i.i.i, %bb25.i.i.i, %bb24.i.i.i - br label %bb40.i.i - -bb40.i.i: ; preds = %bb29.i.i.i, %bb38.i.i, %bb37.i.i - br i1 false, label %bb9.i.i.i.i.preheader, label %bb2.i.i.i87 - -bb9.i.i.i.i.preheader: ; preds = %bb40.i.i - br label %bb9.i.i.i.i - -bb.i.i.i.i84: ; preds = %bb9.i.i.i.i - switch i8 0, label %bb8.i.i.i.i [ - i8 -1, label %bb1.i.i.i.i85 - i8 1, label %bb9.i.i.i.i - ] - -bb1.i.i.i.i85: ; preds = %bb.i.i.i.i84 - br i1 false, label %bb5.i.i.i.i, label %bb2.i.i.i87 - -bb5.i.i.i.i: ; preds = %bb1.i.i.i.i85 - br label %bb2.i.i.i87 - -bb8.i.i.i.i: ; preds = %bb.i.i.i.i84 - br i1 false, label %bb2.i.i.i87, label %bb6.i.i.i95 - -bb9.i.i.i.i: ; preds = %bb.i.i.i.i84, %bb9.i.i.i.i.preheader - br i1 false, label %bb.i.i.i.i84, label %bb10.i.i.i.i - -bb10.i.i.i.i: ; preds = %bb9.i.i.i.i - br label %bb2.i.i.i87 - -bb2.i.i.i87: ; preds = %bb10.i.i.i.i, %bb8.i.i.i.i, %bb5.i.i.i.i, %bb1.i.i.i.i85, %bb40.i.i - br i1 false, label %bb3.i.i.i88, label %decide.exit.i.i - -bb3.i.i.i88: ; preds = %bb2.i.i.i87 - br i1 false, label %bb4.i.i.i90, label %bb1.i23.i.i.i - -bb1.i23.i.i.i: ; preds = %bb3.i.i.i88 - br i1 false, label %decide.exit.i.i, label %bb4.i.i.i90 - -bb4.i.i.i90: ; preds = %bb1.i23.i.i.i, %bb3.i.i.i88 - br i1 false, label %bb1.i9.i.i.i, label %bb5.i.i.i94 - -bb1.i9.i.i.i: ; preds = %bb4.i.i.i90 - br i1 false, label %bb.i.i27.i.i.i.i, label %bb1.i.i28.i.i.i.i - -bb.i.i27.i.i.i.i: ; preds = %bb1.i9.i.i.i - br label %int2lit.exit32.i.i.i.i - -bb1.i.i28.i.i.i.i: ; preds = %bb1.i9.i.i.i - br label %int2lit.exit32.i.i.i.i - -int2lit.exit32.i.i.i.i: ; preds = %bb1.i.i28.i.i.i.i, %bb.i.i27.i.i.i.i - br i1 false, label %bb8.i19.i.i.i, label %bb2.i.i.i.i91 - -bb2.i.i.i.i91: ; preds = %int2lit.exit32.i.i.i.i - br label %bb4.i.i.i.i - -bb3.i.i.i.i92: ; preds = %gcd.exit.i.i.i.i - br label %bb4.i.i.i.i - -bb4.i.i.i.i: ; preds = %bb3.i.i.i.i92, %bb2.i.i.i.i91 - br label %bb3.i.i13.i.i.i - -bb2.i.i12.i.i.i: ; preds = %bb3.i.i13.i.i.i - br label %bb3.i.i13.i.i.i - -bb3.i.i13.i.i.i: ; preds = %bb2.i.i12.i.i.i, %bb4.i.i.i.i - br i1 false, label %gcd.exit.i.i.i.i, label %bb2.i.i12.i.i.i - -gcd.exit.i.i.i.i: ; preds = %bb3.i.i13.i.i.i - br i1 false, label %bb5.i14.i.i.i.preheader, label %bb3.i.i.i.i92 - -bb5.i14.i.i.i.preheader: ; preds = %gcd.exit.i.i.i.i - br label %bb5.i14.i.i.i - -bb5.i14.i.i.i: ; preds = %int2lit.exit.i.i.i.i, %bb5.i14.i.i.i.preheader - br i1 false, label %bb.i.i.i17.i.i.i, label %bb1.i.i.i18.i.i.i - -bb.i.i.i17.i.i.i: ; preds = %bb5.i14.i.i.i - br label %int2lit.exit.i.i.i.i - -bb1.i.i.i18.i.i.i: ; preds = %bb5.i14.i.i.i - br label %int2lit.exit.i.i.i.i - -int2lit.exit.i.i.i.i: ; preds = %bb1.i.i.i18.i.i.i, %bb.i.i.i17.i.i.i - br i1 false, label %bb8.i19.i.i.i.loopexit, label %bb5.i14.i.i.i - -bb8.i19.i.i.i.loopexit: ; preds = %int2lit.exit.i.i.i.i - br label %bb8.i19.i.i.i - -bb8.i19.i.i.i: ; preds = %bb8.i19.i.i.i.loopexit, %int2lit.exit32.i.i.i.i - br i1 false, label %bb5.i.i.i94, label %bb6.i.i.i95 - -bb5.i.i.i94: ; preds = %bb8.i19.i.i.i, %bb4.i.i.i90 - br label %bb.i2.i.i.i - -bb.i2.i.i.i: ; preds = %hpop.exit.i.i.i.i, %bb5.i.i.i94 - br i1 false, label %hpop.exit.i.i.i.i, label %bb1.i.i.i.i.i - -bb1.i.i.i.i.i: ; preds = %bb.i2.i.i.i - br label %bb2.i.i.i.i.i - -bb2.i.i.i.i.i: ; preds = %bb11.i.i.i.i.i, %bb1.i.i.i.i.i - br i1 false, label %bb3.i.i.i.i.i, label %bb12.i.i.i.i.i - -bb3.i.i.i.i.i: ; preds = %bb2.i.i.i.i.i - br i1 false, label %bb4.i.i.i.i.i, label %bb1.i.i.i.i.i.i - -bb1.i.i.i.i.i.i: ; preds = %bb3.i.i.i.i.i - br i1 false, label %bb8.i.i.i.i.i, label %bb3.i.i.i.i.i.i - -bb3.i.i.i.i.i.i: ; preds = %bb1.i.i.i.i.i.i - br i1 false, label %bb4.i.i.i.i.i, label %bb8.i.i.i.i.i - -bb4.i.i.i.i.i: ; preds = %bb3.i.i.i.i.i.i, %bb3.i.i.i.i.i - br i1 false, label %bb5.i.i.i.i.i, label %bb11.i.i.i.i.i - -bb5.i.i.i.i.i: ; preds = %bb4.i.i.i.i.i - br i1 false, label %bb6.i.i.i.i.i, label %bb1.i21.i.i.i.i.i - -bb1.i21.i.i.i.i.i: ; preds = %bb5.i.i.i.i.i - br i1 false, label %bb11.i.i.i.i.i, label %bb3.i24.i.i.i.i.i - -bb3.i24.i.i.i.i.i: ; preds = %bb1.i21.i.i.i.i.i - br i1 false, label %bb6.i.i.i.i.i, label %bb11.i.i.i.i.i - -bb6.i.i.i.i.i: ; preds = %bb3.i24.i.i.i.i.i, %bb5.i.i.i.i.i - br label %bb11.i.i.i.i.i - -bb8.i.i.i.i.i: ; preds = %bb3.i.i.i.i.i.i, %bb1.i.i.i.i.i.i - br i1 false, label %bb9.i.i.i.i.i, label %bb12.i.i.i.i.i - -bb9.i.i.i.i.i: ; preds = %bb8.i.i.i.i.i - br i1 false, label %bb11.i.i.i.i.i, label %bb1.i8.i.i.i.i.i - -bb1.i8.i.i.i.i.i: ; preds = %bb9.i.i.i.i.i - br i1 false, label %bb12.i.i.i.i.i, label %bb3.i11.i.i.i.i.i - -bb3.i11.i.i.i.i.i: ; preds = %bb1.i8.i.i.i.i.i - br i1 false, label %bb11.i.i.i.i.i, label %bb12.i.i.i.i.i - -bb11.i.i.i.i.i: ; preds = %bb3.i11.i.i.i.i.i, %bb9.i.i.i.i.i, %bb6.i.i.i.i.i, %bb3.i24.i.i.i.i.i, %bb1.i21.i.i.i.i.i, %bb4.i.i.i.i.i - br label %bb2.i.i.i.i.i - -bb12.i.i.i.i.i: ; preds = %bb3.i11.i.i.i.i.i, %bb1.i8.i.i.i.i.i, %bb8.i.i.i.i.i, %bb2.i.i.i.i.i - br label %hpop.exit.i.i.i.i - -hpop.exit.i.i.i.i: ; preds = %bb12.i.i.i.i.i, %bb.i2.i.i.i - br i1 false, label %sdecide.exit.i.i.i, label %bb.i2.i.i.i - -sdecide.exit.i.i.i: ; preds = %hpop.exit.i.i.i.i - br label %bb6.i.i.i95 - -bb6.i.i.i95: ; preds = %sdecide.exit.i.i.i, %bb8.i19.i.i.i, %bb8.i.i.i.i - br label %decide.exit.i.i - -decide.exit.i.i: ; preds = %bb6.i.i.i95, %bb1.i23.i.i.i, %bb2.i.i.i87 - br i1 false, label %bb42.i.i, label %sat.exit.i.loopexit.loopexit2 - -bb42.i.i: ; preds = %decide.exit.i.i - br label %bb13.i.i71.outer - -sat.exit.i.loopexit.loopexit: ; preds = %bb24.i.i, %bb1.i68.i.i, %incincs.exit.i.i - br label %sat.exit.i.loopexit - -sat.exit.i.loopexit.loopexit2: ; preds = %decide.exit.i.i, %bb1.i48.i.i, %bb29.i.i - br label %sat.exit.i.loopexit - -sat.exit.i.loopexit: ; preds = %sat.exit.i.loopexit.loopexit2, %sat.exit.i.loopexit.loopexit - br label %sat.exit.i - -sat.exit.i: ; preds = %sat.exit.i.loopexit, %bb1.i61.i.i, %bb8.i.i67, %bb1.i.i.i63, %bb3.i.i59 - br i1 false, label %bb7.i, label %bb2.i96 - -bb2.i96: ; preds = %sat.exit.i - switch i32 0, label %bb5.i99 [ - i32 10, label %bb4.i98 - i32 20, label %bb6.i100 - ] - -bb4.i98: ; preds = %bb2.i96 - br label %bb6.i100 - -bb5.i99: ; preds = %bb2.i96 - br label %bb6.i100 - -bb6.i100: ; preds = %bb5.i99, %bb4.i98, %bb2.i96 - br label %bb7.i - -bb7.i: ; preds = %bb6.i100, %sat.exit.i - br i1 false, label %bb.i1.i, label %picosat_sat.exit - -bb.i1.i: ; preds = %bb7.i - br label %picosat_sat.exit - -picosat_sat.exit: ; preds = %bb.i1.i, %bb7.i - switch i32 0, label %bb166 [ - i32 20, label %bb150 - i32 10, label %bb163 - ] - -bb150: ; preds = %picosat_sat.exit - br i1 false, label %bb152, label %bb151 - -bb151: ; preds = %bb150 - br label %bb152 - -bb152: ; preds = %bb151, %bb150 - br i1 false, label %bb154, label %bb153 - -bb153: ; preds = %bb152 - br label %bb154 - -bb154: ; preds = %bb153, %bb152 - br i1 false, label %bb157, label %bb156 - -bb156: ; preds = %bb154 - br label %bb157 - -bb157: ; preds = %bb156, %bb154 - br i1 false, label %bb159, label %bb158 - -bb158: ; preds = %bb157 - br label %bb159 - -bb159: ; preds = %bb158, %bb157 - br i1 false, label %bb167, label %bb160 - -bb160: ; preds = %bb159 - br label %bb167 - -bb163: ; preds = %picosat_sat.exit - br i1 false, label %bb167, label %bb164 - -bb164: ; preds = %bb163 - br label %bb4.i - -bb.i11: ; preds = %bb4.i - br i1 false, label %bb.i.i12, label %bb1.i.i14 - -bb.i.i12: ; preds = %bb.i11 - unreachable - -bb1.i.i14: ; preds = %bb.i11 - br i1 false, label %bb3.i.i16, label %bb2.i.i15 - -bb2.i.i15: ; preds = %bb1.i.i14 - unreachable - -bb3.i.i16: ; preds = %bb1.i.i14 - br i1 false, label %bb3.i, label %bb7.i.i - -bb7.i.i: ; preds = %bb3.i.i16 - br i1 false, label %bb.i.i.i.i17, label %bb1.i.i.i.i18 - -bb.i.i.i.i17: ; preds = %bb7.i.i - br label %int2lit.exit.i.i - -bb1.i.i.i.i18: ; preds = %bb7.i.i - br label %int2lit.exit.i.i - -int2lit.exit.i.i: ; preds = %bb1.i.i.i.i18, %bb.i.i.i.i17 - br i1 false, label %bb3.i, label %bb9.i.i - -bb9.i.i: ; preds = %int2lit.exit.i.i - br label %bb3.i - -bb3.i: ; preds = %bb9.i.i, %int2lit.exit.i.i, %bb3.i.i16 - br label %bb4.i - -bb4.i: ; preds = %bb3.i, %bb164 - br i1 false, label %bb5.i, label %bb.i11 - -bb5.i: ; preds = %bb4.i - br i1 false, label %bb6.i, label %bb167 - -bb6.i: ; preds = %bb5.i - br label %bb167 - -bb166: ; preds = %picosat_sat.exit - br label %bb167 - -bb167: ; preds = %bb166, %bb6.i, %bb5.i, %bb163, %bb160, %bb159, %picosat_print.exit - br i1 false, label %bb168, label %bb170 - -bb168: ; preds = %bb167 - br i1 false, label %bb170, label %bb169 - -bb169: ; preds = %bb168 - br i1 false, label %bb.i7, label %picosat_time_stamp.exit9 - -bb.i7: ; preds = %bb169 - br label %picosat_time_stamp.exit9 - -picosat_time_stamp.exit9: ; preds = %bb.i7, %bb169 - br label %bb170 - -bb170: ; preds = %picosat_time_stamp.exit9, %bb168, %bb167, %bb129 - br i1 false, label %bb.i.i3, label %picosat_leave.exit - -bb.i.i3: ; preds = %bb170 - br label %picosat_leave.exit - -picosat_leave.exit: ; preds = %bb.i.i3, %bb170 - br i1 false, label %bb1.i.i, label %bb.i.i - -bb.i.i: ; preds = %picosat_leave.exit - unreachable - -bb1.i.i: ; preds = %picosat_leave.exit - br label %bb9.i.i.i - -bb3.i.i.i: ; preds = %bb9.i.i.i - br i1 false, label %bb5.i.i.i, label %bb4.i.i.i - -bb4.i.i.i: ; preds = %bb3.i.i.i - br label %bb5.i.i.i - -bb5.i.i.i: ; preds = %bb4.i.i.i, %bb3.i.i.i - br label %bb9.i.i.i - -bb9.i.i.i: ; preds = %bb5.i.i.i, %bb1.i.i - br i1 false, label %bb10.i.i.i, label %bb3.i.i.i - -bb10.i.i.i: ; preds = %bb9.i.i.i - br i1 false, label %delete.exit.i.i.i, label %bb1.i.i.i.i - -bb1.i.i.i.i: ; preds = %bb10.i.i.i - br label %delete.exit.i.i.i - -delete.exit.i.i.i: ; preds = %bb1.i.i.i.i, %bb10.i.i.i - br i1 false, label %delete_clauses.exit.i.i, label %bb1.i7.i.i.i - -bb1.i7.i.i.i: ; preds = %delete.exit.i.i.i - br label %delete_clauses.exit.i.i - -delete_clauses.exit.i.i: ; preds = %bb1.i7.i.i.i, %delete.exit.i.i.i - br label %bb3.i.i - -bb2.i.i: ; preds = %bb3.i.i - br i1 false, label %lrelease.exit.i.i, label %bb1.i.i23.i.i - -bb1.i.i23.i.i: ; preds = %bb2.i.i - br label %lrelease.exit.i.i - -lrelease.exit.i.i: ; preds = %bb1.i.i23.i.i, %bb2.i.i - br label %bb3.i.i - -bb3.i.i: ; preds = %lrelease.exit.i.i, %delete_clauses.exit.i.i - br i1 false, label %bb4.i.i, label %bb2.i.i - -bb4.i.i: ; preds = %bb3.i.i - br i1 false, label %delete.exit214.i.i, label %bb1.i208.i.i - -bb1.i208.i.i: ; preds = %bb4.i.i - br label %delete.exit214.i.i - -delete.exit214.i.i: ; preds = %bb1.i208.i.i, %bb4.i.i - br i1 false, label %delete.exit203.i.i, label %bb1.i197.i.i - -bb1.i197.i.i: ; preds = %delete.exit214.i.i - br label %delete.exit203.i.i - -delete.exit203.i.i: ; preds = %bb1.i197.i.i, %delete.exit214.i.i - br i1 false, label %delete.exit192.i.i, label %bb1.i186.i.i - -bb1.i186.i.i: ; preds = %delete.exit203.i.i - br label %delete.exit192.i.i - -delete.exit192.i.i: ; preds = %bb1.i186.i.i, %delete.exit203.i.i - br i1 false, label %delete.exit181.i.i, label %bb1.i175.i.i - -bb1.i175.i.i: ; preds = %delete.exit192.i.i - br label %delete.exit181.i.i - -delete.exit181.i.i: ; preds = %bb1.i175.i.i, %delete.exit192.i.i - br i1 false, label %delete.exit170.i.i, label %bb1.i164.i.i - -bb1.i164.i.i: ; preds = %delete.exit181.i.i - br label %delete.exit170.i.i - -delete.exit170.i.i: ; preds = %bb1.i164.i.i, %delete.exit181.i.i - br i1 false, label %delete.exit159.i.i, label %bb1.i153.i.i - -bb1.i153.i.i: ; preds = %delete.exit170.i.i - br label %delete.exit159.i.i - -delete.exit159.i.i: ; preds = %bb1.i153.i.i, %delete.exit170.i.i - br i1 false, label %delete.exit148.i.i, label %bb1.i142.i.i - -bb1.i142.i.i: ; preds = %delete.exit159.i.i - br label %delete.exit148.i.i - -delete.exit148.i.i: ; preds = %bb1.i142.i.i, %delete.exit159.i.i - br i1 false, label %delete.exit137.i.i, label %bb1.i131.i.i - -bb1.i131.i.i: ; preds = %delete.exit148.i.i - br label %delete.exit137.i.i - -delete.exit137.i.i: ; preds = %bb1.i131.i.i, %delete.exit148.i.i - br i1 false, label %delete.exit126.i.i, label %bb1.i120.i.i - -bb1.i120.i.i: ; preds = %delete.exit137.i.i - br label %delete.exit126.i.i - -delete.exit126.i.i: ; preds = %bb1.i120.i.i, %delete.exit137.i.i - br i1 false, label %delete.exit115.i.i, label %bb1.i109.i.i - -bb1.i109.i.i: ; preds = %delete.exit126.i.i - br label %delete.exit115.i.i - -delete.exit115.i.i: ; preds = %bb1.i109.i.i, %delete.exit126.i.i - br i1 false, label %delete.exit104.i.i, label %bb1.i98.i.i - -bb1.i98.i.i: ; preds = %delete.exit115.i.i - br label %delete.exit104.i.i - -delete.exit104.i.i: ; preds = %bb1.i98.i.i, %delete.exit115.i.i - br i1 false, label %delete.exit93.i.i, label %bb1.i87.i.i - -bb1.i87.i.i: ; preds = %delete.exit104.i.i - br label %delete.exit93.i.i - -delete.exit93.i.i: ; preds = %bb1.i87.i.i, %delete.exit104.i.i - br i1 false, label %delete.exit82.i.i, label %bb1.i76.i.i - -bb1.i76.i.i: ; preds = %delete.exit93.i.i - br label %delete.exit82.i.i - -delete.exit82.i.i: ; preds = %bb1.i76.i.i, %delete.exit93.i.i - br i1 false, label %delete.exit71.i.i, label %bb1.i65.i.i - -bb1.i65.i.i: ; preds = %delete.exit82.i.i - br label %delete.exit71.i.i - -delete.exit71.i.i: ; preds = %bb1.i65.i.i, %delete.exit82.i.i - br i1 false, label %delete.exit60.i.i, label %bb1.i54.i.i - -bb1.i54.i.i: ; preds = %delete.exit71.i.i - br label %delete.exit60.i.i - -delete.exit60.i.i: ; preds = %bb1.i54.i.i, %delete.exit71.i.i - br i1 false, label %delete.exit38.i.i, label %bb1.i32.i.i - -bb1.i32.i.i: ; preds = %delete.exit60.i.i - br label %delete.exit38.i.i - -delete.exit38.i.i: ; preds = %bb1.i32.i.i, %delete.exit60.i.i - br i1 false, label %delete.exit18.i.i, label %bb1.i12.i.i - -bb1.i12.i.i: ; preds = %delete.exit38.i.i - br label %delete.exit18.i.i - -delete.exit18.i.i: ; preds = %bb1.i12.i.i, %delete.exit38.i.i - br i1 false, label %picosat_reset.exit, label %bb1.i2.i.i - -bb1.i2.i.i: ; preds = %delete.exit18.i.i - br label %picosat_reset.exit - -picosat_reset.exit: ; preds = %bb1.i2.i.i, %delete.exit18.i.i - br label %bb171 - -bb171: ; preds = %picosat_reset.exit, %bb110 - br i1 false, label %bb173, label %bb172 - -bb172: ; preds = %bb171 - br label %bb173 - -bb173: ; preds = %bb172, %bb171 - br i1 false, label %bb175, label %bb174 - -bb174: ; preds = %bb173 - br label %bb175 - -bb175: ; preds = %bb174, %bb173 - br i1 false, label %bb177, label %bb176 - -bb176: ; preds = %bb175 - br label %bb177 - -bb177: ; preds = %bb176, %bb175 - br i1 false, label %bb179, label %bb178 - -bb178: ; preds = %bb177 - ret i32 0 - -bb179: ; preds = %bb177 - ret i32 0 -} - -define i32 @main(i32 %argc, i8** %argv) nounwind { -entry: - br label %bb2 - -bb: ; preds = %bb2 - br i1 false, label %bb3, label %bb2 - -bb2: ; preds = %bb, %entry - br i1 false, label %bb5.loopexit, label %bb - -bb3: ; preds = %bb - br i1 false, label %bb5, label %bb4 - -bb4: ; preds = %bb3 - br label %bb5 - -bb5.loopexit: ; preds = %bb2 - br label %bb5 - -bb5: ; preds = %bb5.loopexit, %bb4, %bb3 - %0 = call fastcc i32 @picosat_main(i32 %argc, i8** %argv) nounwind ; [#uses=2] - br i1 false, label %bb7, label %bb6 - -bb6: ; preds = %bb5 - ret i32 %0 - -bb7: ; preds = %bb5 - ret i32 %0 -} diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/pr32917.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/pr32917.ll index b2bca62068a3..50bfcce5a3af 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/pr32917.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/pr32917.ll @@ -1,17 +1,27 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=3 < %s | FileCheck %s +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 ; PR 32917 @b = common local_unnamed_addr global i32 0, align 4 @a = common local_unnamed_addr global i32 0, align 4 define i32 @fn2() local_unnamed_addr { -; CHECK-LABEL: define {{[^@]+}}@fn2() local_unnamed_addr -; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4 -; CHECK-NEXT: [[TMP2:%.*]] = sext i32 [[TMP1]] to i64 -; CHECK-NEXT: [[TMP3:%.*]] = inttoptr i64 [[TMP2]] to i32* -; CHECK-NEXT: call fastcc void @fn1(i32* nofree readonly align 4 [[TMP3]]) -; CHECK-NEXT: ret i32 undef +; IS__TUNIT____-LABEL: define {{[^@]+}}@fn2() local_unnamed_addr +; IS__TUNIT____-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4 +; IS__TUNIT____-NEXT: [[TMP2:%.*]] = sext i32 [[TMP1]] to i64 +; IS__TUNIT____-NEXT: [[TMP3:%.*]] = inttoptr i64 [[TMP2]] to i32* +; IS__TUNIT____-NEXT: call fastcc void @fn1(i32* nofree readonly align 4 [[TMP3]]) +; IS__TUNIT____-NEXT: ret i32 undef +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@fn2() local_unnamed_addr +; IS__CGSCC____-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4 +; IS__CGSCC____-NEXT: [[TMP2:%.*]] = sext i32 [[TMP1]] to i64 +; IS__CGSCC____-NEXT: [[TMP3:%.*]] = inttoptr i64 [[TMP2]] to i32* +; IS__CGSCC____-NEXT: call fastcc void @fn1(i32* nofree nonnull readonly align 4 [[TMP3]]) +; IS__CGSCC____-NEXT: ret i32 undef ; %1 = load i32, i32* @b, align 4 %2 = sext i32 %1 to i64 diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/pr33641_remove_arg_dbgvalue.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/pr33641_remove_arg_dbgvalue.ll index de67b8970c23..fff94d452e00 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/pr33641_remove_arg_dbgvalue.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/pr33641_remove_arg_dbgvalue.ll @@ -1,5 +1,8 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=1 < %s | FileCheck %s +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 ; Fix for PR33641. ArgumentPromotion removed the argument to bar but left the call to ; dbg.value which still used the removed argument. diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/profile.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/profile.ll index b9b10cf86005..1f50e1f9e5b1 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/profile.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/profile.ll @@ -1,16 +1,31 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes -; RUN: opt -S -passes='attributor' -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=3 < %s | FileCheck %s +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" ; Checks if !prof metadata is corret in deadargelim. define void @caller() #0 { -; CHECK-LABEL: define {{[^@]+}}@caller() -; CHECK-NEXT: [[X:%.*]] = alloca i32 -; CHECK-NEXT: store i32 42, i32* [[X]], align 4 -; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[X]], align 1 -; CHECK-NEXT: call void @promote_i32_ptr(i32 [[TMP1]]), !prof !0 -; CHECK-NEXT: ret void +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@caller() +; IS__TUNIT_OPM-NEXT: [[X:%.*]] = alloca i32 +; IS__TUNIT_OPM-NEXT: store i32 42, i32* [[X]], align 4 +; IS__TUNIT_OPM-NEXT: call void @promote_i32_ptr(i32* noalias nocapture nonnull readonly align 4 dereferenceable(4) [[X]]), !prof !0 +; IS__TUNIT_OPM-NEXT: ret void +; +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@caller() +; IS__TUNIT_NPM-NEXT: [[X:%.*]] = alloca i32 +; IS__TUNIT_NPM-NEXT: store i32 42, i32* [[X]], align 4 +; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[X]], align 1 +; IS__TUNIT_NPM-NEXT: call void @promote_i32_ptr(i32 [[TMP1]]), !prof !0 +; IS__TUNIT_NPM-NEXT: ret void +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@caller() +; IS__CGSCC____-NEXT: [[X:%.*]] = alloca i32 +; IS__CGSCC____-NEXT: store i32 42, i32* [[X]], align 4 +; IS__CGSCC____-NEXT: call void @promote_i32_ptr(i32* noalias nonnull readonly align 4 dereferenceable(4) [[X]]), !prof !0 +; IS__CGSCC____-NEXT: ret void ; %x = alloca i32 store i32 42, i32* %x @@ -19,13 +34,25 @@ define void @caller() #0 { } define internal void @promote_i32_ptr(i32* %xp) { -; CHECK-LABEL: define {{[^@]+}}@promote_i32_ptr -; CHECK-SAME: (i32 [[TMP0:%.*]]) -; CHECK-NEXT: [[XP_PRIV:%.*]] = alloca i32 -; CHECK-NEXT: store i32 [[TMP0]], i32* [[XP_PRIV]] -; CHECK-NEXT: [[X:%.*]] = load i32, i32* [[XP_PRIV]], align 4 -; CHECK-NEXT: call void @use_i32(i32 [[X]]) -; CHECK-NEXT: ret void +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@promote_i32_ptr +; IS__TUNIT_OPM-SAME: (i32* noalias nocapture nonnull readonly align 4 dereferenceable(4) [[XP:%.*]]) +; IS__TUNIT_OPM-NEXT: [[X:%.*]] = load i32, i32* [[XP]], align 4 +; IS__TUNIT_OPM-NEXT: call void @use_i32(i32 [[X]]) +; IS__TUNIT_OPM-NEXT: ret void +; +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@promote_i32_ptr +; IS__TUNIT_NPM-SAME: (i32 [[TMP0:%.*]]) +; IS__TUNIT_NPM-NEXT: [[XP_PRIV:%.*]] = alloca i32 +; IS__TUNIT_NPM-NEXT: store i32 [[TMP0]], i32* [[XP_PRIV]] +; IS__TUNIT_NPM-NEXT: [[X:%.*]] = load i32, i32* [[XP_PRIV]], align 4 +; IS__TUNIT_NPM-NEXT: call void @use_i32(i32 [[X]]) +; IS__TUNIT_NPM-NEXT: ret void +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@promote_i32_ptr +; IS__CGSCC____-SAME: (i32* nocapture nonnull readonly align 4 dereferenceable(4) [[XP:%.*]]) +; IS__CGSCC____-NEXT: [[X:%.*]] = load i32, i32* [[XP]], align 4 +; IS__CGSCC____-NEXT: call void @use_i32(i32 [[X]]) +; IS__CGSCC____-NEXT: ret void ; %x = load i32, i32* %xp call void @use_i32(i32 %x) diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/reserve-tbaa.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/reserve-tbaa.ll index d8d582b12563..dbceea83a4fe 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/reserve-tbaa.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/reserve-tbaa.ll @@ -1,5 +1,8 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes -; RUN: opt -S -passes='attributor' -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=3 < %s | FileCheck %s +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 ; PR17906 ; When we promote two arguments in a single function with different types, @@ -14,13 +17,20 @@ @d = global i8 0, align 1 define internal fastcc void @fn(i32* nocapture readonly %p1, i64* nocapture readonly %p2) { -; CHECK-LABEL: define {{[^@]+}}@fn -; CHECK-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P1:%.*]]) -; CHECK-NEXT: entry: -; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @g, align 4, !tbaa !0 -; CHECK-NEXT: [[CONV1:%.*]] = trunc i32 [[TMP0]] to i8 -; CHECK-NEXT: store i8 [[CONV1]], i8* @d, align 1, !tbaa !4 -; CHECK-NEXT: ret void +; IS__TUNIT____-LABEL: define {{[^@]+}}@fn +; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P1:%.*]]) +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: [[TMP0:%.*]] = load i32, i32* @g, align 4, !tbaa !0 +; IS__TUNIT____-NEXT: [[CONV1:%.*]] = trunc i32 [[TMP0]] to i8 +; IS__TUNIT____-NEXT: store i8 [[CONV1]], i8* @d, align 1, !tbaa !4 +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@fn() +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: [[TMP0:%.*]] = load i32, i32* @g, align 4, !tbaa !0 +; IS__CGSCC____-NEXT: [[CONV1:%.*]] = trunc i32 [[TMP0]] to i8 +; IS__CGSCC____-NEXT: store i8 [[CONV1]], i8* @d, align 1, !tbaa !4 +; IS__CGSCC____-NEXT: ret void ; entry: %0 = load i64, i64* %p2, align 8, !tbaa !1 @@ -32,14 +42,23 @@ entry: } define i32 @main() { -; CHECK-LABEL: define {{[^@]+}}@main() -; CHECK-NEXT: entry: -; CHECK-NEXT: [[TMP0:%.*]] = load i32**, i32*** @e, align 8, !tbaa !5 -; CHECK-NEXT: store i32* @g, i32** [[TMP0]], align 8, !tbaa !5 -; CHECK-NEXT: [[TMP1:%.*]] = load i32*, i32** @a, align 8, !tbaa !5 -; CHECK-NEXT: store i32 1, i32* [[TMP1]], align 4, !tbaa !0 -; CHECK-NEXT: call fastcc void @fn(i32* nofree nonnull readonly align 4 dereferenceable(4) @g) -; CHECK-NEXT: ret i32 0 +; IS__TUNIT____-LABEL: define {{[^@]+}}@main() +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: [[TMP0:%.*]] = load i32**, i32*** @e, align 8, !tbaa !5 +; IS__TUNIT____-NEXT: store i32* @g, i32** [[TMP0]], align 8, !tbaa !5 +; IS__TUNIT____-NEXT: [[TMP1:%.*]] = load i32*, i32** @a, align 8, !tbaa !5 +; IS__TUNIT____-NEXT: store i32 1, i32* [[TMP1]], align 4, !tbaa !0 +; IS__TUNIT____-NEXT: call fastcc void @fn(i32* nofree nonnull readonly align 4 dereferenceable(4) @g) +; IS__TUNIT____-NEXT: ret i32 0 +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@main() +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: [[TMP0:%.*]] = load i32**, i32*** @e, align 8, !tbaa !5 +; IS__CGSCC____-NEXT: store i32* @g, i32** [[TMP0]], align 8, !tbaa !5 +; IS__CGSCC____-NEXT: [[TMP1:%.*]] = load i32*, i32** @a, align 8, !tbaa !5 +; IS__CGSCC____-NEXT: store i32 1, i32* [[TMP1]], align 4, !tbaa !0 +; IS__CGSCC____-NEXT: call fastcc void @fn() +; IS__CGSCC____-NEXT: ret i32 0 ; entry: %0 = load i32**, i32*** @e, align 8, !tbaa !8 diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/sret.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/sret.ll index 5e3e9881c509..d1d2c556b971 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/sret.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/sret.ll @@ -1,19 +1,43 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes -; RUN: opt -S -passes='attributor' -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=4 < %s | FileCheck %s +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=4 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=4 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-pc-windows-msvc" define internal void @add({i32, i32}* %this, i32* sret %r) { -; CHECK-LABEL: define {{[^@]+}}@add -; CHECK-SAME: ({ i32, i32 }* noalias nocapture nofree nonnull readonly align 8 dereferenceable(8) [[THIS:%.*]], i32* noalias nocapture nofree nonnull sret writeonly align 4 dereferenceable(4) [[R:%.*]]) -; CHECK-NEXT: [[AP:%.*]] = getelementptr { i32, i32 }, { i32, i32 }* [[THIS]], i32 0, i32 0 -; CHECK-NEXT: [[BP:%.*]] = getelementptr { i32, i32 }, { i32, i32 }* [[THIS]], i32 0, i32 1 -; CHECK-NEXT: [[A:%.*]] = load i32, i32* [[AP]], align 8 -; CHECK-NEXT: [[B:%.*]] = load i32, i32* [[BP]], align 4 -; CHECK-NEXT: [[AB:%.*]] = add i32 [[A]], [[B]] -; CHECK-NEXT: store i32 [[AB]], i32* [[R]], align 4 -; CHECK-NEXT: ret void +; +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@add +; IS__TUNIT_OPM-SAME: ({ i32, i32 }* nocapture nofree nonnull readonly align 8 dereferenceable(8) [[THIS:%.*]], i32* nocapture nofree nonnull sret writeonly align 4 dereferenceable(4) [[R:%.*]]) +; IS__TUNIT_OPM-NEXT: [[AP:%.*]] = getelementptr { i32, i32 }, { i32, i32 }* [[THIS]], i32 0, i32 0 +; IS__TUNIT_OPM-NEXT: [[BP:%.*]] = getelementptr { i32, i32 }, { i32, i32 }* [[THIS]], i32 0, i32 1 +; IS__TUNIT_OPM-NEXT: [[A:%.*]] = load i32, i32* [[AP]], align 8 +; IS__TUNIT_OPM-NEXT: [[B:%.*]] = load i32, i32* [[BP]], align 4 +; IS__TUNIT_OPM-NEXT: [[AB:%.*]] = add i32 [[A]], [[B]] +; IS__TUNIT_OPM-NEXT: store i32 [[AB]], i32* [[R]], align 4 +; IS__TUNIT_OPM-NEXT: ret void +; +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@add +; IS__TUNIT_NPM-SAME: ({ i32, i32 }* noalias nocapture nofree nonnull readonly align 8 dereferenceable(8) [[THIS:%.*]], i32* noalias nocapture nofree nonnull sret writeonly align 4 dereferenceable(4) [[R:%.*]]) +; IS__TUNIT_NPM-NEXT: [[AP:%.*]] = getelementptr { i32, i32 }, { i32, i32 }* [[THIS]], i32 0, i32 0 +; IS__TUNIT_NPM-NEXT: [[BP:%.*]] = getelementptr { i32, i32 }, { i32, i32 }* [[THIS]], i32 0, i32 1 +; IS__TUNIT_NPM-NEXT: [[A:%.*]] = load i32, i32* [[AP]], align 8 +; IS__TUNIT_NPM-NEXT: [[B:%.*]] = load i32, i32* [[BP]], align 4 +; IS__TUNIT_NPM-NEXT: [[AB:%.*]] = add i32 [[A]], [[B]] +; IS__TUNIT_NPM-NEXT: store i32 [[AB]], i32* [[R]], align 4 +; IS__TUNIT_NPM-NEXT: ret void +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@add +; IS__CGSCC____-SAME: ({ i32, i32 }* nocapture nofree nonnull readonly align 4 dereferenceable(8) [[THIS:%.*]], i32* nocapture nofree nonnull sret writeonly align 4 dereferenceable(4) [[R:%.*]]) +; IS__CGSCC____-NEXT: [[AP:%.*]] = getelementptr { i32, i32 }, { i32, i32 }* [[THIS]], i32 0, i32 0 +; IS__CGSCC____-NEXT: [[BP:%.*]] = getelementptr { i32, i32 }, { i32, i32 }* [[THIS]], i32 0, i32 1 +; IS__CGSCC____-NEXT: [[A:%.*]] = load i32, i32* [[AP]], align 4 +; IS__CGSCC____-NEXT: [[B:%.*]] = load i32, i32* [[BP]], align 4 +; IS__CGSCC____-NEXT: [[AB:%.*]] = add i32 [[A]], [[B]] +; IS__CGSCC____-NEXT: store i32 [[AB]], i32* [[R]], align 4 +; IS__CGSCC____-NEXT: ret void ; %ap = getelementptr {i32, i32}, {i32, i32}* %this, i32 0, i32 0 %bp = getelementptr {i32, i32}, {i32, i32}* %this, i32 0, i32 1 @@ -25,11 +49,29 @@ define internal void @add({i32, i32}* %this, i32* sret %r) { } define void @f() { -; CHECK-LABEL: define {{[^@]+}}@f() -; CHECK-NEXT: [[R:%.*]] = alloca i32 -; CHECK-NEXT: [[PAIR:%.*]] = alloca { i32, i32 } -; CHECK-NEXT: call void @add({ i32, i32 }* noalias nocapture nofree nonnull readonly align 8 dereferenceable(8) [[PAIR]], i32* noalias nocapture nofree nonnull sret writeonly align 4 dereferenceable(4) [[R]]) -; CHECK-NEXT: ret void +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@f() +; IS__TUNIT_OPM-NEXT: [[R:%.*]] = alloca i32 +; IS__TUNIT_OPM-NEXT: [[PAIR:%.*]] = alloca { i32, i32 } +; IS__TUNIT_OPM-NEXT: call void @add({ i32, i32 }* nocapture nofree nonnull readonly align 8 dereferenceable(8) [[PAIR]], i32* nocapture nofree nonnull sret writeonly align 4 dereferenceable(4) [[R]]) +; IS__TUNIT_OPM-NEXT: ret void +; +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@f() +; IS__TUNIT_NPM-NEXT: [[R:%.*]] = alloca i32 +; IS__TUNIT_NPM-NEXT: [[PAIR:%.*]] = alloca { i32, i32 } +; IS__TUNIT_NPM-NEXT: call void @add({ i32, i32 }* noalias nocapture nofree nonnull readonly align 8 dereferenceable(8) [[PAIR]], i32* noalias nocapture nofree nonnull sret writeonly align 4 dereferenceable(4) [[R]]) +; IS__TUNIT_NPM-NEXT: ret void +; +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f() +; IS__CGSCC_OPM-NEXT: [[R:%.*]] = alloca i32 +; IS__CGSCC_OPM-NEXT: [[PAIR:%.*]] = alloca { i32, i32 } +; IS__CGSCC_OPM-NEXT: call void @add({ i32, i32 }* nofree nonnull readonly align 8 dereferenceable(8) [[PAIR]], i32* nofree nonnull sret writeonly align 4 dereferenceable(4) [[R]]) +; IS__CGSCC_OPM-NEXT: ret void +; +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f() +; IS__CGSCC_NPM-NEXT: [[R:%.*]] = alloca i32 +; IS__CGSCC_NPM-NEXT: [[PAIR:%.*]] = alloca { i32, i32 } +; IS__CGSCC_NPM-NEXT: call void @add({ i32, i32 }* noalias nofree nonnull readonly align 8 dereferenceable(8) [[PAIR]], i32* noalias nofree nonnull sret writeonly align 4 dereferenceable(4) [[R]]) +; IS__CGSCC_NPM-NEXT: ret void ; %r = alloca i32 %pair = alloca {i32, i32} diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/tail.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/tail.ll index 6141c5f3073b..7502ae651c4f 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/tail.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/tail.ll @@ -1,5 +1,8 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes -; RUN: opt -S -passes='attributor' -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=4 < %s | FileCheck %s +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=4 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=4 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 ; PR14710 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" @@ -9,29 +12,48 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" declare i8* @foo(%pair*) define internal void @bar(%pair* byval %Data) { -; CHECK-LABEL: define {{[^@]+}}@bar -; CHECK-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]]) -; CHECK-NEXT: [[DATA_PRIV:%.*]] = alloca [[PAIR:%.*]] -; CHECK-NEXT: [[DATA_PRIV_CAST:%.*]] = bitcast %pair* [[DATA_PRIV]] to i32* -; CHECK-NEXT: store i32 [[TMP0]], i32* [[DATA_PRIV_CAST]] -; CHECK-NEXT: [[DATA_PRIV_0_1:%.*]] = getelementptr [[PAIR]], %pair* [[DATA_PRIV]], i32 0, i32 1 -; CHECK-NEXT: store i32 [[TMP1]], i32* [[DATA_PRIV_0_1]] -; CHECK-NEXT: [[TMP3:%.*]] = call i8* @foo(%pair* [[DATA_PRIV]]) -; CHECK-NEXT: ret void +; IS________OPM-LABEL: define {{[^@]+}}@bar +; IS________OPM-SAME: (%pair* noalias byval [[DATA:%.*]]) +; IS________OPM-NEXT: [[TMP1:%.*]] = tail call i8* @foo(%pair* [[DATA]]) +; IS________OPM-NEXT: ret void +; +; IS________NPM-LABEL: define {{[^@]+}}@bar +; IS________NPM-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]]) +; IS________NPM-NEXT: [[DATA_PRIV:%.*]] = alloca [[PAIR:%.*]] +; IS________NPM-NEXT: [[DATA_PRIV_CAST:%.*]] = bitcast %pair* [[DATA_PRIV]] to i32* +; IS________NPM-NEXT: store i32 [[TMP0]], i32* [[DATA_PRIV_CAST]] +; IS________NPM-NEXT: [[DATA_PRIV_0_1:%.*]] = getelementptr [[PAIR]], %pair* [[DATA_PRIV]], i32 0, i32 1 +; IS________NPM-NEXT: store i32 [[TMP1]], i32* [[DATA_PRIV_0_1]] +; IS________NPM-NEXT: [[TMP3:%.*]] = call i8* @foo(%pair* [[DATA_PRIV]]) +; IS________NPM-NEXT: ret void ; tail call i8* @foo(%pair* %Data) ret void } define void @zed(%pair* byval %Data) { -; CHECK-LABEL: define {{[^@]+}}@zed -; CHECK-SAME: (%pair* noalias nocapture readonly byval [[DATA:%.*]]) -; CHECK-NEXT: [[DATA_CAST:%.*]] = bitcast %pair* [[DATA]] to i32* -; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[DATA_CAST]], align 1 -; CHECK-NEXT: [[DATA_0_1:%.*]] = getelementptr [[PAIR:%.*]], %pair* [[DATA]], i32 0, i32 1 -; CHECK-NEXT: [[TMP2:%.*]] = load i32, i32* [[DATA_0_1]], align 1 -; CHECK-NEXT: call void @bar(i32 [[TMP1]], i32 [[TMP2]]) -; CHECK-NEXT: ret void +; IS________OPM-LABEL: define {{[^@]+}}@zed +; IS________OPM-SAME: (%pair* noalias nocapture readonly byval [[DATA:%.*]]) +; IS________OPM-NEXT: call void @bar(%pair* noalias nocapture readonly byval [[DATA]]) +; IS________OPM-NEXT: ret void +; +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@zed +; IS__TUNIT_NPM-SAME: (%pair* noalias nocapture readonly byval [[DATA:%.*]]) +; IS__TUNIT_NPM-NEXT: [[DATA_CAST:%.*]] = bitcast %pair* [[DATA]] to i32* +; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[DATA_CAST]], align 1 +; IS__TUNIT_NPM-NEXT: [[DATA_0_1:%.*]] = getelementptr [[PAIR:%.*]], %pair* [[DATA]], i32 0, i32 1 +; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[DATA_0_1]], align 1 +; IS__TUNIT_NPM-NEXT: call void @bar(i32 [[TMP1]], i32 [[TMP2]]) +; IS__TUNIT_NPM-NEXT: ret void +; +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@zed +; IS__CGSCC_NPM-SAME: (%pair* noalias nocapture nonnull readonly byval dereferenceable(8) [[DATA:%.*]]) +; IS__CGSCC_NPM-NEXT: [[DATA_CAST:%.*]] = bitcast %pair* [[DATA]] to i32* +; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[DATA_CAST]], align 1 +; IS__CGSCC_NPM-NEXT: [[DATA_0_1:%.*]] = getelementptr [[PAIR:%.*]], %pair* [[DATA]], i32 0, i32 1 +; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[DATA_0_1]], align 1 +; IS__CGSCC_NPM-NEXT: call void @bar(i32 [[TMP1]], i32 [[TMP2]]) +; IS__CGSCC_NPM-NEXT: ret void ; call void @bar(%pair* byval %Data) ret void diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/variadic.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/variadic.ll index b637d39a50de..694c2ef250ef 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/variadic.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/variadic.ll @@ -1,5 +1,8 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes -; RUN: opt -S -passes='attributor' -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=1 < %s | FileCheck %s +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 ; Unused arguments from variadic functions cannot be eliminated as that changes ; their classiciation according to the SysV amd64 ABI. Clang and other frontends @@ -28,11 +31,17 @@ entry: ; Function Attrs: nounwind uwtable define internal void @callee_t0f(i8* nocapture readnone %tp13, i8* nocapture readnone %tp14, i8* nocapture readnone %tp15, i8* nocapture readnone %tp16, i8* nocapture readnone %tp17, ...) { -; CHECK-LABEL: define {{[^@]+}}@callee_t0f -; CHECK-SAME: (i8* noalias nocapture nofree nonnull readnone [[TP13:%.*]], i8* noalias nocapture nofree nonnull readnone [[TP14:%.*]], i8* noalias nocapture nofree nonnull readnone [[TP15:%.*]], i8* noalias nocapture nofree nonnull readnone [[TP16:%.*]], i8* noalias nocapture nofree nonnull readnone [[TP17:%.*]], ...) -; CHECK-NEXT: entry: -; CHECK-NEXT: call void @sink(i32 0) -; CHECK-NEXT: ret void +; IS__TUNIT____-LABEL: define {{[^@]+}}@callee_t0f +; IS__TUNIT____-SAME: (i8* noalias nocapture nofree nonnull readnone [[TP13:%.*]], i8* noalias nocapture nofree nonnull readnone [[TP14:%.*]], i8* noalias nocapture nofree nonnull readnone [[TP15:%.*]], i8* noalias nocapture nofree nonnull readnone [[TP16:%.*]], i8* noalias nocapture nofree nonnull readnone [[TP17:%.*]], ...) +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: call void @sink(i32 0) +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@callee_t0f +; IS__CGSCC____-SAME: (i8* nocapture nofree nonnull readnone [[TP13:%.*]], i8* nocapture nofree nonnull readnone [[TP14:%.*]], i8* nocapture nofree nonnull readnone [[TP15:%.*]], i8* nocapture nofree nonnull readnone [[TP16:%.*]], i8* nocapture nofree nonnull readnone [[TP17:%.*]], ...) +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: call void @sink(i32 0) +; IS__CGSCC____-NEXT: ret void ; entry: call void @sink(i32 0) diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/2008-06-09-WeakProp.ll b/llvm/test/Transforms/Attributor/IPConstantProp/2008-06-09-WeakProp.ll index d05e3b113191..8669f0794826 100644 --- a/llvm/test/Transforms/Attributor/IPConstantProp/2008-06-09-WeakProp.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/2008-06-09-WeakProp.ll @@ -1,5 +1,9 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes -; RUN: opt < %s -passes=attributor -S | FileCheck %s +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 + ; Should not propagate the result of a weak function. ; PR2411 diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/2009-09-24-byval-ptr.ll b/llvm/test/Transforms/Attributor/IPConstantProp/2009-09-24-byval-ptr.ll index 26b37d7a67eb..1b7b90d4471d 100644 --- a/llvm/test/Transforms/Attributor/IPConstantProp/2009-09-24-byval-ptr.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/2009-09-24-byval-ptr.ll @@ -1,10 +1,41 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=6 < %s | FileCheck %s +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=6 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=6 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 + ; Don't constant-propagate byval pointers, since they are not pointers! ; PR5038 %struct.MYstr = type { i8, i32 } @mystr = internal global %struct.MYstr zeroinitializer ; <%struct.MYstr*> [#uses=3] define internal void @vfu1(%struct.MYstr* byval align 4 %u) nounwind { +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@vfu1 +; IS__CGSCC_OPM-SAME: (%struct.MYstr* noalias nocapture nofree nonnull writeonly byval align 4 dereferenceable(1) [[U:%.*]]) +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = getelementptr [[STRUCT_MYSTR:%.*]], %struct.MYstr* [[U]], i32 0, i32 1 +; IS__CGSCC_OPM-NEXT: store i32 99, i32* [[TMP0]], align 4 +; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U]], i32 0, i32 0 +; IS__CGSCC_OPM-NEXT: store i8 97, i8* [[TMP1]], align 4 +; IS__CGSCC_OPM-NEXT: br label [[RETURN:%.*]] +; IS__CGSCC_OPM: return: +; IS__CGSCC_OPM-NEXT: ret void +; +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@vfu1 +; IS__CGSCC_NPM-SAME: (i8 [[TMP0:%.*]], i32 [[TMP1:%.*]]) +; IS__CGSCC_NPM-NEXT: entry: +; IS__CGSCC_NPM-NEXT: [[U_PRIV:%.*]] = alloca [[STRUCT_MYSTR:%.*]] +; IS__CGSCC_NPM-NEXT: [[U_PRIV_CAST:%.*]] = bitcast %struct.MYstr* [[U_PRIV]] to i8* +; IS__CGSCC_NPM-NEXT: store i8 [[TMP0]], i8* [[U_PRIV_CAST]] +; IS__CGSCC_NPM-NEXT: [[U_PRIV_0_1:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U_PRIV]], i32 0, i32 1 +; IS__CGSCC_NPM-NEXT: store i32 [[TMP1]], i32* [[U_PRIV_0_1]] +; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U_PRIV]], i32 0, i32 1 +; IS__CGSCC_NPM-NEXT: store i32 99, i32* [[TMP2]], align 4 +; IS__CGSCC_NPM-NEXT: [[TMP3:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U_PRIV]], i32 0, i32 0 +; IS__CGSCC_NPM-NEXT: store i8 97, i8* [[TMP3]], align 4 +; IS__CGSCC_NPM-NEXT: br label [[RETURN:%.*]] +; IS__CGSCC_NPM: return: +; IS__CGSCC_NPM-NEXT: ret void +; entry: %0 = getelementptr %struct.MYstr, %struct.MYstr* %u, i32 0, i32 1 ; [#uses=1] store i32 99, i32* %0, align 4 @@ -17,21 +48,42 @@ return: ; preds = %entry } define internal i32 @vfu2(%struct.MYstr* byval align 4 %u) nounwind readonly { -; CHECK-LABEL: define {{[^@]+}}@vfu2 -; CHECK-SAME: (i8 [[TMP0:%.*]], i32 [[TMP1:%.*]]) -; CHECK-NEXT: entry: -; CHECK-NEXT: [[U_PRIV:%.*]] = alloca [[STRUCT_MYSTR:%.*]] -; CHECK-NEXT: [[U_PRIV_CAST:%.*]] = bitcast %struct.MYstr* [[U_PRIV]] to i8* -; CHECK-NEXT: store i8 [[TMP0]], i8* [[U_PRIV_CAST]] -; CHECK-NEXT: [[U_PRIV_0_1:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U_PRIV]], i32 0, i32 1 -; CHECK-NEXT: store i32 [[TMP1]], i32* [[U_PRIV_0_1]] -; CHECK-NEXT: [[TMP2:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* @mystr, i32 0, i32 1 -; CHECK-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]] -; CHECK-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* @mystr, i32 0, i32 0 -; CHECK-NEXT: [[TMP5:%.*]] = load i8, i8* [[TMP4]], align 8 -; CHECK-NEXT: [[TMP6:%.*]] = zext i8 [[TMP5]] to i32 -; CHECK-NEXT: [[TMP7:%.*]] = add i32 [[TMP6]], [[TMP3]] -; CHECK-NEXT: ret i32 [[TMP7]] +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@vfu2 +; IS__TUNIT_OPM-SAME: (%struct.MYstr* noalias nocapture nofree nonnull readonly byval align 8 dereferenceable(8) [[U:%.*]]) +; IS__TUNIT_OPM-NEXT: entry: +; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = getelementptr [[STRUCT_MYSTR:%.*]], %struct.MYstr* @mystr, i32 0, i32 1 +; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4 +; IS__TUNIT_OPM-NEXT: [[TMP2:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* @mystr, i32 0, i32 0 +; IS__TUNIT_OPM-NEXT: [[TMP3:%.*]] = load i8, i8* [[TMP2]], align 8 +; IS__TUNIT_OPM-NEXT: [[TMP4:%.*]] = zext i8 [[TMP3]] to i32 +; IS__TUNIT_OPM-NEXT: [[TMP5:%.*]] = add i32 [[TMP4]], [[TMP1]] +; IS__TUNIT_OPM-NEXT: ret i32 [[TMP5]] +; +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@vfu2 +; IS__TUNIT_NPM-SAME: (i8 [[TMP0:%.*]], i32 [[TMP1:%.*]]) +; IS__TUNIT_NPM-NEXT: entry: +; IS__TUNIT_NPM-NEXT: [[U_PRIV:%.*]] = alloca [[STRUCT_MYSTR:%.*]] +; IS__TUNIT_NPM-NEXT: [[U_PRIV_CAST:%.*]] = bitcast %struct.MYstr* [[U_PRIV]] to i8* +; IS__TUNIT_NPM-NEXT: store i8 [[TMP0]], i8* [[U_PRIV_CAST]] +; IS__TUNIT_NPM-NEXT: [[U_PRIV_0_1:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U_PRIV]], i32 0, i32 1 +; IS__TUNIT_NPM-NEXT: store i32 [[TMP1]], i32* [[U_PRIV_0_1]] +; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* @mystr, i32 0, i32 1 +; IS__TUNIT_NPM-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4 +; IS__TUNIT_NPM-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* @mystr, i32 0, i32 0 +; IS__TUNIT_NPM-NEXT: [[TMP5:%.*]] = load i8, i8* [[TMP4]], align 8 +; IS__TUNIT_NPM-NEXT: [[TMP6:%.*]] = zext i8 [[TMP5]] to i32 +; IS__TUNIT_NPM-NEXT: [[TMP7:%.*]] = add i32 [[TMP6]], [[TMP3]] +; IS__TUNIT_NPM-NEXT: ret i32 [[TMP7]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@vfu2() +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: [[TMP0:%.*]] = getelementptr [[STRUCT_MYSTR:%.*]], %struct.MYstr* @mystr, i32 0, i32 1 +; IS__CGSCC____-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4 +; IS__CGSCC____-NEXT: [[TMP2:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* @mystr, i32 0, i32 0 +; IS__CGSCC____-NEXT: [[TMP3:%.*]] = load i8, i8* [[TMP2]], align 4 +; IS__CGSCC____-NEXT: [[TMP4:%.*]] = zext i8 [[TMP3]] to i32 +; IS__CGSCC____-NEXT: [[TMP5:%.*]] = add i32 [[TMP4]], [[TMP1]] +; IS__CGSCC____-NEXT: ret i32 [[TMP5]] ; entry: %0 = getelementptr %struct.MYstr, %struct.MYstr* %u, i32 0, i32 1 ; [#uses=1] @@ -44,14 +96,24 @@ entry: } define i32 @unions() nounwind { -; CHECK-LABEL: define {{[^@]+}}@unions() -; CHECK-NEXT: entry: -; CHECK-NEXT: [[MYSTR_CAST:%.*]] = bitcast %struct.MYstr* @mystr to i8* -; CHECK-NEXT: [[TMP0:%.*]] = load i8, i8* [[MYSTR_CAST]], align 1 -; CHECK-NEXT: [[MYSTR_0_1:%.*]] = getelementptr [[STRUCT_MYSTR:%.*]], %struct.MYstr* @mystr, i32 0, i32 1 -; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[MYSTR_0_1]], align 1 -; CHECK-NEXT: [[RESULT:%.*]] = call i32 @vfu2(i8 [[TMP0]], i32 [[TMP1]]) -; CHECK-NEXT: ret i32 [[RESULT]] +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@unions() +; IS__TUNIT_OPM-NEXT: entry: +; IS__TUNIT_OPM-NEXT: [[RESULT:%.*]] = call i32 @vfu2(%struct.MYstr* nofree nonnull readonly byval align 8 dereferenceable(8) @mystr) +; IS__TUNIT_OPM-NEXT: ret i32 [[RESULT]] +; +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@unions() +; IS__TUNIT_NPM-NEXT: entry: +; IS__TUNIT_NPM-NEXT: [[MYSTR_CAST:%.*]] = bitcast %struct.MYstr* @mystr to i8* +; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load i8, i8* [[MYSTR_CAST]], align 1 +; IS__TUNIT_NPM-NEXT: [[MYSTR_0_1:%.*]] = getelementptr [[STRUCT_MYSTR:%.*]], %struct.MYstr* @mystr, i32 0, i32 1 +; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[MYSTR_0_1]], align 1 +; IS__TUNIT_NPM-NEXT: [[RESULT:%.*]] = call i32 @vfu2(i8 [[TMP0]], i32 [[TMP1]]) +; IS__TUNIT_NPM-NEXT: ret i32 [[RESULT]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@unions() +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: [[RESULT:%.*]] = call i32 @vfu2() +; IS__CGSCC____-NEXT: ret i32 [[RESULT]] ; entry: call void @vfu1(%struct.MYstr* byval align 4 @mystr) nounwind @@ -60,23 +122,67 @@ entry: } define internal i32 @vfu2_v2(%struct.MYstr* byval align 4 %u) nounwind readonly { -; CHECK-LABEL: define {{[^@]+}}@vfu2_v2 -; CHECK-SAME: (i8 [[TMP0:%.*]], i32 [[TMP1:%.*]]) -; CHECK-NEXT: entry: -; CHECK-NEXT: [[U_PRIV:%.*]] = alloca [[STRUCT_MYSTR:%.*]] -; CHECK-NEXT: [[U_PRIV_CAST:%.*]] = bitcast %struct.MYstr* [[U_PRIV]] to i8* -; CHECK-NEXT: store i8 [[TMP0]], i8* [[U_PRIV_CAST]] -; CHECK-NEXT: [[U_PRIV_0_1:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U_PRIV]], i32 0, i32 1 -; CHECK-NEXT: store i32 [[TMP1]], i32* [[U_PRIV_0_1]] -; CHECK-NEXT: [[Z:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U_PRIV]], i32 0, i32 1 -; CHECK-NEXT: store i32 99, i32* [[Z]], align 4 -; CHECK-NEXT: [[TMP2:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U_PRIV]], i32 0, i32 1 -; CHECK-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]] -; CHECK-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U_PRIV]], i32 0, i32 0 -; CHECK-NEXT: [[TMP5:%.*]] = load i8, i8* [[TMP4]], align 8 -; CHECK-NEXT: [[TMP6:%.*]] = zext i8 [[TMP5]] to i32 -; CHECK-NEXT: [[TMP7:%.*]] = add i32 [[TMP6]], [[TMP3]] -; CHECK-NEXT: ret i32 [[TMP7]] +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@vfu2_v2 +; IS__TUNIT_OPM-SAME: (%struct.MYstr* noalias nocapture nofree nonnull byval align 8 dereferenceable(8) [[U:%.*]]) +; IS__TUNIT_OPM-NEXT: entry: +; IS__TUNIT_OPM-NEXT: [[Z:%.*]] = getelementptr [[STRUCT_MYSTR:%.*]], %struct.MYstr* [[U]], i32 0, i32 1 +; IS__TUNIT_OPM-NEXT: store i32 99, i32* [[Z]], align 4 +; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U]], i32 0, i32 1 +; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4 +; IS__TUNIT_OPM-NEXT: [[TMP2:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U]], i32 0, i32 0 +; IS__TUNIT_OPM-NEXT: [[TMP3:%.*]] = load i8, i8* [[TMP2]], align 8 +; IS__TUNIT_OPM-NEXT: [[TMP4:%.*]] = zext i8 [[TMP3]] to i32 +; IS__TUNIT_OPM-NEXT: [[TMP5:%.*]] = add i32 [[TMP4]], [[TMP1]] +; IS__TUNIT_OPM-NEXT: ret i32 [[TMP5]] +; +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@vfu2_v2 +; IS__TUNIT_NPM-SAME: (i8 [[TMP0:%.*]], i32 [[TMP1:%.*]]) +; IS__TUNIT_NPM-NEXT: entry: +; IS__TUNIT_NPM-NEXT: [[U_PRIV:%.*]] = alloca [[STRUCT_MYSTR:%.*]] +; IS__TUNIT_NPM-NEXT: [[U_PRIV_CAST:%.*]] = bitcast %struct.MYstr* [[U_PRIV]] to i8* +; IS__TUNIT_NPM-NEXT: store i8 [[TMP0]], i8* [[U_PRIV_CAST]] +; IS__TUNIT_NPM-NEXT: [[U_PRIV_0_1:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U_PRIV]], i32 0, i32 1 +; IS__TUNIT_NPM-NEXT: store i32 [[TMP1]], i32* [[U_PRIV_0_1]] +; IS__TUNIT_NPM-NEXT: [[Z:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U_PRIV]], i32 0, i32 1 +; IS__TUNIT_NPM-NEXT: store i32 99, i32* [[Z]], align 4 +; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U_PRIV]], i32 0, i32 1 +; IS__TUNIT_NPM-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4 +; IS__TUNIT_NPM-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U_PRIV]], i32 0, i32 0 +; IS__TUNIT_NPM-NEXT: [[TMP5:%.*]] = load i8, i8* [[TMP4]], align 8 +; IS__TUNIT_NPM-NEXT: [[TMP6:%.*]] = zext i8 [[TMP5]] to i32 +; IS__TUNIT_NPM-NEXT: [[TMP7:%.*]] = add i32 [[TMP6]], [[TMP3]] +; IS__TUNIT_NPM-NEXT: ret i32 [[TMP7]] +; +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@vfu2_v2 +; IS__CGSCC_OPM-SAME: (%struct.MYstr* noalias nocapture nofree nonnull byval align 4 dereferenceable(1) [[U:%.*]]) +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: [[Z:%.*]] = getelementptr [[STRUCT_MYSTR:%.*]], %struct.MYstr* [[U]], i32 0, i32 1 +; IS__CGSCC_OPM-NEXT: store i32 99, i32* [[Z]], align 4 +; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U]], i32 0, i32 1 +; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4 +; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U]], i32 0, i32 0 +; IS__CGSCC_OPM-NEXT: [[TMP3:%.*]] = load i8, i8* [[TMP2]], align 4 +; IS__CGSCC_OPM-NEXT: [[TMP4:%.*]] = zext i8 [[TMP3]] to i32 +; IS__CGSCC_OPM-NEXT: [[TMP5:%.*]] = add i32 [[TMP4]], [[TMP1]] +; IS__CGSCC_OPM-NEXT: ret i32 [[TMP5]] +; +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@vfu2_v2 +; IS__CGSCC_NPM-SAME: (i8 [[TMP0:%.*]], i32 [[TMP1:%.*]]) +; IS__CGSCC_NPM-NEXT: entry: +; IS__CGSCC_NPM-NEXT: [[U_PRIV:%.*]] = alloca [[STRUCT_MYSTR:%.*]] +; IS__CGSCC_NPM-NEXT: [[U_PRIV_CAST:%.*]] = bitcast %struct.MYstr* [[U_PRIV]] to i8* +; IS__CGSCC_NPM-NEXT: store i8 [[TMP0]], i8* [[U_PRIV_CAST]] +; IS__CGSCC_NPM-NEXT: [[U_PRIV_0_1:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U_PRIV]], i32 0, i32 1 +; IS__CGSCC_NPM-NEXT: store i32 [[TMP1]], i32* [[U_PRIV_0_1]] +; IS__CGSCC_NPM-NEXT: [[Z:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U_PRIV]], i32 0, i32 1 +; IS__CGSCC_NPM-NEXT: store i32 99, i32* [[Z]], align 4 +; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U_PRIV]], i32 0, i32 1 +; IS__CGSCC_NPM-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4 +; IS__CGSCC_NPM-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U_PRIV]], i32 0, i32 0 +; IS__CGSCC_NPM-NEXT: [[TMP5:%.*]] = load i8, i8* [[TMP4]], align 4 +; IS__CGSCC_NPM-NEXT: [[TMP6:%.*]] = zext i8 [[TMP5]] to i32 +; IS__CGSCC_NPM-NEXT: [[TMP7:%.*]] = add i32 [[TMP6]], [[TMP3]] +; IS__CGSCC_NPM-NEXT: ret i32 [[TMP7]] ; entry: %z = getelementptr %struct.MYstr, %struct.MYstr* %u, i32 0, i32 1 @@ -91,14 +197,33 @@ entry: } define i32 @unions_v2() nounwind { -; CHECK-LABEL: define {{[^@]+}}@unions_v2() -; CHECK-NEXT: entry: -; CHECK-NEXT: [[MYSTR_CAST:%.*]] = bitcast %struct.MYstr* @mystr to i8* -; CHECK-NEXT: [[TMP0:%.*]] = load i8, i8* [[MYSTR_CAST]], align 1 -; CHECK-NEXT: [[MYSTR_0_1:%.*]] = getelementptr [[STRUCT_MYSTR:%.*]], %struct.MYstr* @mystr, i32 0, i32 1 -; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[MYSTR_0_1]], align 1 -; CHECK-NEXT: [[RESULT:%.*]] = call i32 @vfu2_v2(i8 [[TMP0]], i32 [[TMP1]]) -; CHECK-NEXT: ret i32 [[RESULT]] +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@unions_v2() +; IS__TUNIT_OPM-NEXT: entry: +; IS__TUNIT_OPM-NEXT: [[RESULT:%.*]] = call i32 @vfu2_v2(%struct.MYstr* nofree nonnull readonly byval align 8 dereferenceable(8) @mystr) +; IS__TUNIT_OPM-NEXT: ret i32 [[RESULT]] +; +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@unions_v2() +; IS__TUNIT_NPM-NEXT: entry: +; IS__TUNIT_NPM-NEXT: [[MYSTR_CAST:%.*]] = bitcast %struct.MYstr* @mystr to i8* +; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load i8, i8* [[MYSTR_CAST]], align 1 +; IS__TUNIT_NPM-NEXT: [[MYSTR_0_1:%.*]] = getelementptr [[STRUCT_MYSTR:%.*]], %struct.MYstr* @mystr, i32 0, i32 1 +; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[MYSTR_0_1]], align 1 +; IS__TUNIT_NPM-NEXT: [[RESULT:%.*]] = call i32 @vfu2_v2(i8 [[TMP0]], i32 [[TMP1]]) +; IS__TUNIT_NPM-NEXT: ret i32 [[RESULT]] +; +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@unions_v2() +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: [[RESULT:%.*]] = call i32 @vfu2_v2(%struct.MYstr* noalias nofree nonnull readnone byval align 8 dereferenceable(8) @mystr) +; IS__CGSCC_OPM-NEXT: ret i32 [[RESULT]] +; +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@unions_v2() +; IS__CGSCC_NPM-NEXT: entry: +; IS__CGSCC_NPM-NEXT: [[MYSTR_CAST1:%.*]] = bitcast %struct.MYstr* @mystr to i8* +; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = load i8, i8* [[MYSTR_CAST1]], align 8 +; IS__CGSCC_NPM-NEXT: [[MYSTR_0_12:%.*]] = getelementptr [[STRUCT_MYSTR:%.*]], %struct.MYstr* @mystr, i32 0, i32 1 +; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[MYSTR_0_12]], align 1 +; IS__CGSCC_NPM-NEXT: [[RESULT:%.*]] = call i32 @vfu2_v2(i8 [[TMP0]], i32 [[TMP1]]) +; IS__CGSCC_NPM-NEXT: ret i32 [[RESULT]] ; entry: call void @vfu1(%struct.MYstr* byval align 4 @mystr) nounwind diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/PR16052.ll b/llvm/test/Transforms/Attributor/IPConstantProp/PR16052.ll index e53d4fa4306b..786873f8dedf 100644 --- a/llvm/test/Transforms/Attributor/IPConstantProp/PR16052.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/PR16052.ll @@ -1,14 +1,22 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=2 < %s | FileCheck %s +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" define i64 @fn2() { -; CHECK-LABEL: define {{[^@]+}}@fn2() -; CHECK-NEXT: entry: -; CHECK-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 undef) #1, !range !0 -; CHECK-NEXT: ret i64 [[CALL2]] +; NOT_TUNIT_NPM-LABEL: define {{[^@]+}}@fn2() +; NOT_TUNIT_NPM-NEXT: entry: +; NOT_TUNIT_NPM-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 undef) +; NOT_TUNIT_NPM-NEXT: ret i64 [[CALL2]] +; +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@fn2() +; IS__TUNIT_NPM-NEXT: entry: +; IS__TUNIT_NPM-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 undef) #1, !range !0 +; IS__TUNIT_NPM-NEXT: ret i64 [[CALL2]] ; entry: %conv = sext i32 undef to i64 @@ -18,13 +26,21 @@ entry: } define i64 @fn2b(i32 %arg) { -; CHECK-LABEL: define {{[^@]+}}@fn2b -; CHECK-SAME: (i32 [[ARG:%.*]]) -; CHECK-NEXT: entry: -; CHECK-NEXT: [[CONV:%.*]] = sext i32 [[ARG]] to i64 -; CHECK-NEXT: [[DIV:%.*]] = sdiv i64 8, [[CONV]] -; CHECK-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 [[DIV]]) #1, !range !0 -; CHECK-NEXT: ret i64 [[CALL2]] +; NOT_TUNIT_NPM-LABEL: define {{[^@]+}}@fn2b +; NOT_TUNIT_NPM-SAME: (i32 [[ARG:%.*]]) +; NOT_TUNIT_NPM-NEXT: entry: +; NOT_TUNIT_NPM-NEXT: [[CONV:%.*]] = sext i32 [[ARG]] to i64 +; NOT_TUNIT_NPM-NEXT: [[DIV:%.*]] = sdiv i64 8, [[CONV]] +; NOT_TUNIT_NPM-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 [[DIV]]) +; NOT_TUNIT_NPM-NEXT: ret i64 [[CALL2]] +; +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@fn2b +; IS__TUNIT_NPM-SAME: (i32 [[ARG:%.*]]) +; IS__TUNIT_NPM-NEXT: entry: +; IS__TUNIT_NPM-NEXT: [[CONV:%.*]] = sext i32 [[ARG]] to i64 +; IS__TUNIT_NPM-NEXT: [[DIV:%.*]] = sdiv i64 8, [[CONV]] +; IS__TUNIT_NPM-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 [[DIV]]) #1, !range !0 +; IS__TUNIT_NPM-NEXT: ret i64 [[CALL2]] ; entry: %conv = sext i32 %arg to i64 @@ -34,10 +50,19 @@ entry: } define i64 @fn2c() { -; CHECK-LABEL: define {{[^@]+}}@fn2c() -; CHECK-NEXT: entry: -; CHECK-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 42) #1, !range !0 -; CHECK-NEXT: ret i64 [[CALL2]] +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@fn2c() +; IS__TUNIT_OPM-NEXT: entry: +; IS__TUNIT_OPM-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 42) +; IS__TUNIT_OPM-NEXT: ret i64 [[CALL2]] +; +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@fn2c() +; IS__TUNIT_NPM-NEXT: entry: +; IS__TUNIT_NPM-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 42) #1, !range !0 +; IS__TUNIT_NPM-NEXT: ret i64 [[CALL2]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@fn2c() +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: ret i64 42 ; entry: %conv = sext i32 undef to i64 diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/PR26044.ll b/llvm/test/Transforms/Attributor/IPConstantProp/PR26044.ll index cf77bbf78436..d4eef4c20642 100644 --- a/llvm/test/Transforms/Attributor/IPConstantProp/PR26044.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/PR26044.ll @@ -1,21 +1,42 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=1 < %s | FileCheck %s +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" define void @fn2(i32* %P, i1 %C) { -; CHECK-LABEL: define {{[^@]+}}@fn2 -; CHECK-SAME: (i32* nocapture nofree [[P:%.*]], i1 %C) -; CHECK-NEXT: entry: -; CHECK-NEXT: br label [[IF_END:%.*]] -; CHECK: for.cond1: -; CHECK-NEXT: br i1 %C, label %if.end, label %exit -; CHECK: if.end: -; CHECK-NEXT: [[E_2:%.*]] = phi i32* [ %P, %entry ], [ null, %for.cond1 ] -; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[E_2]], align 4 -; CHECK-NEXT: [[CALL:%.*]] = call i32 @fn1(i32 [[TMP0]]) -; CHECK-NEXT: store i32 [[CALL]], i32* [[P]] -; CHECK-NEXT: br label %for.cond1 +; +; IS__TUNIT____-LABEL: define {{[^@]+}}@fn2 +; IS__TUNIT____-SAME: (i32* nocapture nofree [[P:%.*]], i1 [[C:%.*]]) +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: br label [[IF_END:%.*]] +; IS__TUNIT____: for.cond1: +; IS__TUNIT____-NEXT: br i1 [[C]], label [[IF_END]], label [[EXIT:%.*]] +; IS__TUNIT____: if.end: +; IS__TUNIT____-NEXT: [[E_2:%.*]] = phi i32* [ [[P]], [[ENTRY:%.*]] ], [ null, [[FOR_COND1:%.*]] ] +; IS__TUNIT____-NEXT: [[TMP0:%.*]] = load i32, i32* [[E_2]], align 4 +; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32 @fn1(i32 [[TMP0]]) +; IS__TUNIT____-NEXT: store i32 [[CALL]], i32* [[P]] +; IS__TUNIT____-NEXT: br label [[FOR_COND1]] +; IS__TUNIT____: exit: +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@fn2 +; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull align 4 dereferenceable(4) [[P:%.*]], i1 [[C:%.*]]) +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: br label [[IF_END:%.*]] +; IS__CGSCC____: for.cond1: +; IS__CGSCC____-NEXT: br i1 [[C]], label [[IF_END]], label [[EXIT:%.*]] +; IS__CGSCC____: if.end: +; IS__CGSCC____-NEXT: [[E_2:%.*]] = phi i32* [ [[P]], [[ENTRY:%.*]] ], [ null, [[FOR_COND1:%.*]] ] +; IS__CGSCC____-NEXT: [[TMP0:%.*]] = load i32, i32* [[E_2]], align 4 +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32 @fn1(i32 [[TMP0]]) +; IS__CGSCC____-NEXT: store i32 [[CALL]], i32* [[P]], align 4 +; IS__CGSCC____-NEXT: br label [[FOR_COND1]] +; IS__CGSCC____: exit: +; IS__CGSCC____-NEXT: ret void ; entry: br label %if.end @@ -48,18 +69,51 @@ entry: } define void @fn_no_null_opt(i32* %P, i1 %C) "null-pointer-is-valid"="true" { -; CHECK-LABEL: define {{[^@]+}}@fn_no_null_opt -; CHECK-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i1 %C) -; CHECK-NEXT: entry: -; CHECK-NEXT: br label [[IF_END:%.*]] -; CHECK: for.cond1: -; CHECK-NEXT: br i1 %C, label %if.end, label %exit -; CHECK: if.end: -; CHECK-NEXT: [[E_2:%.*]] = phi i32* [ undef, %entry ], [ null, %for.cond1 ] -; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* null, align 4 -; CHECK-NEXT: [[CALL:%.*]] = call i32 @fn0(i32 [[TMP0]]) -; CHECK-NEXT: store i32 [[CALL]], i32* [[P]] -; CHECK-NEXT: br label %for.cond1 +; +; IS__TUNIT____-LABEL: define {{[^@]+}}@fn_no_null_opt +; IS__TUNIT____-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i1 [[C:%.*]]) +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: br label [[IF_END:%.*]] +; IS__TUNIT____: for.cond1: +; IS__TUNIT____-NEXT: br i1 [[C]], label [[IF_END]], label [[EXIT:%.*]] +; IS__TUNIT____: if.end: +; IS__TUNIT____-NEXT: [[E_2:%.*]] = phi i32* [ undef, [[ENTRY:%.*]] ], [ null, [[FOR_COND1:%.*]] ] +; IS__TUNIT____-NEXT: [[TMP0:%.*]] = load i32, i32* null, align 4 +; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32 @fn0(i32 [[TMP0]]) +; IS__TUNIT____-NEXT: store i32 [[CALL]], i32* [[P]] +; IS__TUNIT____-NEXT: br label [[FOR_COND1]] +; IS__TUNIT____: exit: +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@fn_no_null_opt +; IS__CGSCC_OPM-SAME: (i32* nocapture nofree writeonly align 4 dereferenceable_or_null(4) [[P:%.*]], i1 [[C:%.*]]) +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: br label [[IF_END:%.*]] +; IS__CGSCC_OPM: for.cond1: +; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[IF_END]], label [[EXIT:%.*]] +; IS__CGSCC_OPM: if.end: +; IS__CGSCC_OPM-NEXT: [[E_2:%.*]] = phi i32* [ undef, [[ENTRY:%.*]] ], [ null, [[FOR_COND1:%.*]] ] +; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = load i32, i32* null, align 4 +; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call i32 @fn0(i32 [[TMP0]]) +; IS__CGSCC_OPM-NEXT: store i32 [[CALL]], i32* [[P]], align 4 +; IS__CGSCC_OPM-NEXT: br label [[FOR_COND1]] +; IS__CGSCC_OPM: exit: +; IS__CGSCC_OPM-NEXT: ret void +; +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@fn_no_null_opt +; IS__CGSCC_NPM-SAME: (i32* nocapture nofree writeonly align 4 dereferenceable_or_null(4) [[P:%.*]], i1 [[C:%.*]]) +; IS__CGSCC_NPM-NEXT: entry: +; IS__CGSCC_NPM-NEXT: br label [[IF_END:%.*]] +; IS__CGSCC_NPM: for.cond1: +; IS__CGSCC_NPM-NEXT: br i1 [[C]], label [[IF_END]], label [[EXIT:%.*]] +; IS__CGSCC_NPM: if.end: +; IS__CGSCC_NPM-NEXT: [[E_2:%.*]] = phi i32* [ undef, [[ENTRY:%.*]] ], [ null, [[FOR_COND1:%.*]] ] +; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = load i32, i32* null, align 536870912 +; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call i32 @fn0(i32 [[TMP0]]) +; IS__CGSCC_NPM-NEXT: store i32 [[CALL]], i32* [[P]], align 4 +; IS__CGSCC_NPM-NEXT: br label [[FOR_COND1]] +; IS__CGSCC_NPM: exit: +; IS__CGSCC_NPM-NEXT: ret void ; entry: br label %if.end diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/PR43857.ll b/llvm/test/Transforms/Attributor/IPConstantProp/PR43857.ll index 16f45449d38f..bb8283125ebe 100644 --- a/llvm/test/Transforms/Attributor/IPConstantProp/PR43857.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/PR43857.ll @@ -1,5 +1,8 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes -; RUN: opt -S -passes=attributor -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=1 < %s | FileCheck %s +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 %struct.wobble = type { i32 } %struct.zot = type { %struct.wobble, %struct.wobble, %struct.wobble } @@ -17,10 +20,16 @@ bb: } define void @baz(<8 x i32> %arg) local_unnamed_addr { -; CHECK-LABEL: define {{[^@]+}}@baz -; CHECK-SAME: (<8 x i32> [[ARG:%.*]]) local_unnamed_addr -; CHECK-NEXT: bb: -; CHECK-NEXT: ret void +; IS__TUNIT____-LABEL: define {{[^@]+}}@baz +; IS__TUNIT____-SAME: (<8 x i32> [[ARG:%.*]]) local_unnamed_addr +; IS__TUNIT____-NEXT: bb: +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@baz +; IS__CGSCC____-SAME: (<8 x i32> [[ARG:%.*]]) local_unnamed_addr +; IS__CGSCC____-NEXT: bb: +; IS__CGSCC____-NEXT: [[TMP1:%.*]] = extractvalue [[STRUCT_ZOT:%.*]] undef, 0, 0 +; IS__CGSCC____-NEXT: ret void ; bb: %tmp = call %struct.zot @widget(<8 x i32> %arg) diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/arg-count-mismatch.ll b/llvm/test/Transforms/Attributor/IPConstantProp/arg-count-mismatch.ll index 64c9fce32300..2a6bd94e1daf 100644 --- a/llvm/test/Transforms/Attributor/IPConstantProp/arg-count-mismatch.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/arg-count-mismatch.ll @@ -1,5 +1,8 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=1 < %s | FileCheck %s +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 ; The original C source looked like this: ; @@ -76,11 +79,18 @@ define internal i16 @bar2(i16 %p1, i16 %p2) { ; been provided), define dso_local i16 @vararg_tests(i16 %a) { -; CHECK-LABEL: define {{[^@]+}}@vararg_tests -; CHECK-SAME: (i16 [[A:%.*]]) -; CHECK-NEXT: [[CALL2:%.*]] = call i16 bitcast (i16 (i16, i16, ...)* @vararg_no_prop to i16 (i16)*)(i16 7) -; CHECK-NEXT: [[ADD:%.*]] = add i16 7, [[CALL2]] -; CHECK-NEXT: ret i16 [[ADD]] +; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@vararg_tests +; NOT_CGSCC_OPM-SAME: (i16 [[A:%.*]]) +; NOT_CGSCC_OPM-NEXT: [[CALL2:%.*]] = call i16 bitcast (i16 (i16, i16, ...)* @vararg_no_prop to i16 (i16)*)(i16 7) +; NOT_CGSCC_OPM-NEXT: [[ADD:%.*]] = add i16 7, [[CALL2]] +; NOT_CGSCC_OPM-NEXT: ret i16 [[ADD]] +; +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@vararg_tests +; IS__CGSCC_OPM-SAME: (i16 [[A:%.*]]) +; IS__CGSCC_OPM-NEXT: [[CALL1:%.*]] = call i16 (i16, ...) @vararg_prop(i16 7, i16 8, i16 [[A]]) +; IS__CGSCC_OPM-NEXT: [[CALL2:%.*]] = call i16 bitcast (i16 (i16, i16, ...)* @vararg_no_prop to i16 (i16)*)(i16 7) +; IS__CGSCC_OPM-NEXT: [[ADD:%.*]] = add i16 [[CALL1]], [[CALL2]] +; IS__CGSCC_OPM-NEXT: ret i16 [[ADD]] ; %call1 = call i16 (i16, ...) @vararg_prop(i16 7, i16 8, i16 %a) %call2 = call i16 bitcast (i16 (i16, i16, ...) * @vararg_no_prop to i16 (i16) *) (i16 7) @@ -89,6 +99,10 @@ define dso_local i16 @vararg_tests(i16 %a) { } define internal i16 @vararg_prop(i16 %p1, ...) { +; IS__CGSCC____-LABEL: define {{[^@]+}}@vararg_prop +; IS__CGSCC____-SAME: (i16 returned [[P1:%.*]], ...) +; IS__CGSCC____-NEXT: ret i16 7 +; ret i16 %p1 } diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/arg-type-mismatch.ll b/llvm/test/Transforms/Attributor/IPConstantProp/arg-type-mismatch.ll index a91e8eeee5ee..576a6fb9f084 100644 --- a/llvm/test/Transforms/Attributor/IPConstantProp/arg-type-mismatch.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/arg-type-mismatch.ll @@ -1,5 +1,8 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=1 < %s | FileCheck %s +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 ; This test is just to verify that we do not crash/assert due to mismatch in ; argument type between the caller and callee. diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/comdat-ipo.ll b/llvm/test/Transforms/Attributor/IPConstantProp/comdat-ipo.ll index 2fcde7a92288..41428b3ff5e4 100644 --- a/llvm/test/Transforms/Attributor/IPConstantProp/comdat-ipo.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/comdat-ipo.ll @@ -1,5 +1,8 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=1 < %s | FileCheck %s +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 ; See PR26774 diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/dangling-block-address.ll b/llvm/test/Transforms/Attributor/IPConstantProp/dangling-block-address.ll index 679067650870..489ddb66da71 100644 --- a/llvm/test/Transforms/Attributor/IPConstantProp/dangling-block-address.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/dangling-block-address.ll @@ -1,23 +1,51 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes -; RUN: opt -S -passes='internalize,attributor' -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=1 < %s | FileCheck %s +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 ; PR5569 ; IPSCCP should prove that the blocks are dead and delete them, and ; properly handle the dangling blockaddress constants. -; CHECK: @bar.l = internal constant [2 x i8*] [i8* inttoptr (i32 1 to i8*), i8* inttoptr (i32 1 to i8*)] +; NOT_CGSCC_OPM: @bar.l = internal constant [2 x i8*] [i8* inttoptr (i32 1 to i8*), i8* inttoptr (i32 1 to i8*)] +; IS__CGSCC_OPM: @bar.l = internal constant [2 x i8*] [i8* blockaddress(@bar, %lab0), i8* blockaddress(@bar, %end)] @code = global [5 x i32] [i32 0, i32 0, i32 0, i32 0, i32 1], align 4 ; <[5 x i32]*> [#uses=0] @bar.l = internal constant [2 x i8*] [i8* blockaddress(@bar, %lab0), i8* blockaddress(@bar, %end)] ; <[2 x i8*]*> [#uses=1] -define void @foo(i32 %x) nounwind readnone { +define internal void @foo(i32 %x) nounwind readnone { +; IS__CGSCC____-LABEL: define {{[^@]+}}@foo +; IS__CGSCC____-SAME: (i32 [[X:%.*]]) +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: [[B:%.*]] = alloca i32, align 4 +; IS__CGSCC____-NEXT: store volatile i32 -1, i32* [[B]] +; IS__CGSCC____-NEXT: ret void +; entry: %b = alloca i32, align 4 ; [#uses=1] store volatile i32 -1, i32* %b ret void } -define void @bar(i32* nocapture %pc) nounwind readonly { +define internal void @bar(i32* nocapture %pc) nounwind readonly { +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@bar +; IS__CGSCC_OPM-SAME: (i32* nocapture [[PC:%.*]]) +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: br label [[INDIRECTGOTO:%.*]] +; IS__CGSCC_OPM: lab0: +; IS__CGSCC_OPM-NEXT: [[INDVAR_NEXT:%.*]] = add i32 [[INDVAR:%.*]], 1 +; IS__CGSCC_OPM-NEXT: br label [[INDIRECTGOTO]] +; IS__CGSCC_OPM: end: +; IS__CGSCC_OPM-NEXT: ret void +; IS__CGSCC_OPM: indirectgoto: +; IS__CGSCC_OPM-NEXT: [[INDVAR]] = phi i32 [ [[INDVAR_NEXT]], [[LAB0:%.*]] ], [ 0, [[ENTRY:%.*]] ] +; IS__CGSCC_OPM-NEXT: [[PC_ADDR_0:%.*]] = getelementptr i32, i32* [[PC]], i32 [[INDVAR]] +; IS__CGSCC_OPM-NEXT: [[TMP1_PN:%.*]] = load i32, i32* [[PC_ADDR_0]] +; IS__CGSCC_OPM-NEXT: [[INDIRECT_GOTO_DEST_IN:%.*]] = getelementptr inbounds [2 x i8*], [2 x i8*]* @bar.l, i32 0, i32 [[TMP1_PN]] +; IS__CGSCC_OPM-NEXT: [[INDIRECT_GOTO_DEST:%.*]] = load i8*, i8** [[INDIRECT_GOTO_DEST_IN]] +; IS__CGSCC_OPM-NEXT: indirectbr i8* [[INDIRECT_GOTO_DEST]], [label [[LAB0]], label %end] +; entry: br label %indirectgoto @@ -38,6 +66,10 @@ indirectgoto: ; preds = %lab0, %entry } define i32 @main() nounwind readnone { +; CHECK-LABEL: define {{[^@]+}}@main() +; CHECK-NEXT: entry: +; CHECK-NEXT: ret i32 0 +; entry: ret i32 0 } diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/deadarg.ll b/llvm/test/Transforms/Attributor/IPConstantProp/deadarg.ll index c84f4dee2487..b5742a49e64d 100644 --- a/llvm/test/Transforms/Attributor/IPConstantProp/deadarg.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/deadarg.ll @@ -1,6 +1,14 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes -; RUN: opt -passes=attributor -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=1 -disable-output < %s +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 define internal void @foo(i32 %X) { +; CHECK-LABEL: define {{[^@]+}}@foo +; CHECK-SAME: (i32 [[X:%.*]]) +; CHECK-NEXT: call void @foo(i32 [[X]]) +; CHECK-NEXT: ret void +; call void @foo( i32 %X ) ret void } diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/fp-bc-icmp-const-fold.ll b/llvm/test/Transforms/Attributor/IPConstantProp/fp-bc-icmp-const-fold.ll index 8d8dd00cf53c..727785260f76 100644 --- a/llvm/test/Transforms/Attributor/IPConstantProp/fp-bc-icmp-const-fold.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/fp-bc-icmp-const-fold.ll @@ -1,5 +1,8 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=1 < %s | FileCheck %s +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 target datalayout = "E-m:e-i64:64-n32:64" target triple = "powerpc64-bgq-linux" diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/global.ll b/llvm/test/Transforms/Attributor/IPConstantProp/global.ll index 7b186f05976e..4326239f1932 100644 --- a/llvm/test/Transforms/Attributor/IPConstantProp/global.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/global.ll @@ -1,5 +1,8 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=1 < %s | FileCheck %s +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 @_ZL6test1g = internal global i32 42, align 4 diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/multiple_callbacks.ll b/llvm/test/Transforms/Attributor/IPConstantProp/multiple_callbacks.ll index 3a3f0fe210f5..bbef0302b6ce 100644 --- a/llvm/test/Transforms/Attributor/IPConstantProp/multiple_callbacks.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/multiple_callbacks.ll @@ -1,5 +1,8 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=1 < %s | FileCheck %s +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 ; ; ; /---------------------------------------| diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/musttail-call.ll b/llvm/test/Transforms/Attributor/IPConstantProp/musttail-call.ll index d14c06760cb7..fa2a136fcc73 100644 --- a/llvm/test/Transforms/Attributor/IPConstantProp/musttail-call.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/musttail-call.ll @@ -1,26 +1,46 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=4 < %s | FileCheck %s +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=4 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=4 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 ; PR36485 ; musttail call result can't be replaced with a constant, unless the call can be removed declare i32 @external() define i8* @start(i8 %v) { -; CHECK-LABEL: define {{[^@]+}}@start -; CHECK-SAME: (i8 [[V:%.*]]) -; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[V]], 0 -; CHECK-NEXT: br i1 [[C1]], label [[TRUE:%.*]], label [[FALSE:%.*]] -; CHECK: true: -; CHECK-NEXT: [[CA:%.*]] = musttail call i8* @side_effects(i8 [[V]]) -; CHECK-NEXT: ret i8* [[CA]] -; CHECK: false: -; CHECK-NEXT: [[C2:%.*]] = icmp eq i8 [[V]], 1 -; CHECK-NEXT: br i1 [[C2]], label [[C2_TRUE:%.*]], label [[C2_FALSE:%.*]] -; CHECK: c2_true: -; CHECK-NEXT: ret i8* null -; CHECK: c2_false: -; CHECK-NEXT: [[CA2:%.*]] = musttail call i8* @dont_zap_me(i8 undef) -; CHECK-NEXT: ret i8* [[CA2]] +; IS__TUNIT____-LABEL: define {{[^@]+}}@start +; IS__TUNIT____-SAME: (i8 [[V:%.*]]) +; IS__TUNIT____-NEXT: [[C1:%.*]] = icmp eq i8 [[V]], 0 +; IS__TUNIT____-NEXT: br i1 [[C1]], label [[TRUE:%.*]], label [[FALSE:%.*]] +; IS__TUNIT____: true: +; IS__TUNIT____-NEXT: [[CA:%.*]] = musttail call i8* @side_effects(i8 [[V]]) +; IS__TUNIT____-NEXT: ret i8* [[CA]] +; IS__TUNIT____: false: +; IS__TUNIT____-NEXT: [[C2:%.*]] = icmp eq i8 [[V]], 1 +; IS__TUNIT____-NEXT: br i1 [[C2]], label [[C2_TRUE:%.*]], label [[C2_FALSE:%.*]] +; IS__TUNIT____: c2_true: +; IS__TUNIT____-NEXT: ret i8* null +; IS__TUNIT____: c2_false: +; IS__TUNIT____-NEXT: [[CA2:%.*]] = musttail call i8* @dont_zap_me(i8 undef) +; IS__TUNIT____-NEXT: ret i8* [[CA2]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@start +; IS__CGSCC____-SAME: (i8 [[V:%.*]]) +; IS__CGSCC____-NEXT: [[C1:%.*]] = icmp eq i8 [[V]], 0 +; IS__CGSCC____-NEXT: br i1 [[C1]], label [[TRUE:%.*]], label [[FALSE:%.*]] +; IS__CGSCC____: true: +; IS__CGSCC____-NEXT: [[CA:%.*]] = musttail call noalias align 536870912 i8* @side_effects(i8 [[V]]) +; IS__CGSCC____-NEXT: ret i8* [[CA]] +; IS__CGSCC____: false: +; IS__CGSCC____-NEXT: [[C2:%.*]] = icmp eq i8 [[V]], 1 +; IS__CGSCC____-NEXT: br i1 [[C2]], label [[C2_TRUE:%.*]], label [[C2_FALSE:%.*]] +; IS__CGSCC____: c2_true: +; IS__CGSCC____-NEXT: [[CA1:%.*]] = musttail call noalias align 536870912 i8* @no_side_effects(i8 [[V]]) +; IS__CGSCC____-NEXT: ret i8* [[CA1]] +; IS__CGSCC____: c2_false: +; IS__CGSCC____-NEXT: [[CA2:%.*]] = musttail call noalias align 536870912 i8* @dont_zap_me(i8 [[V]]) +; IS__CGSCC____-NEXT: ret i8* [[CA2]] ; %c1 = icmp eq i8 %v, 0 br i1 %c1, label %true, label %false @@ -41,11 +61,17 @@ c2_false: } define internal i8* @side_effects(i8 %v) { -; CHECK-LABEL: define {{[^@]+}}@side_effects -; CHECK-SAME: (i8 [[V:%.*]]) -; CHECK-NEXT: [[I1:%.*]] = call i32 @external() -; CHECK-NEXT: [[CA:%.*]] = musttail call i8* @start(i8 [[V]]) -; CHECK-NEXT: ret i8* [[CA]] +; IS__TUNIT____-LABEL: define {{[^@]+}}@side_effects +; IS__TUNIT____-SAME: (i8 [[V:%.*]]) +; IS__TUNIT____-NEXT: [[I1:%.*]] = call i32 @external() +; IS__TUNIT____-NEXT: [[CA:%.*]] = musttail call i8* @start(i8 [[V]]) +; IS__TUNIT____-NEXT: ret i8* [[CA]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@side_effects +; IS__CGSCC____-SAME: (i8 [[V:%.*]]) +; IS__CGSCC____-NEXT: [[I1:%.*]] = call i32 @external() +; IS__CGSCC____-NEXT: [[CA:%.*]] = musttail call noalias align 536870912 i8* @start(i8 [[V]]) +; IS__CGSCC____-NEXT: ret i8* [[CA]] ; %i1 = call i32 @external() @@ -60,14 +86,23 @@ define internal i8* @side_effects(i8 %v) { } define internal i8* @no_side_effects(i8 %v) readonly nounwind { +; IS__CGSCC____-LABEL: define {{[^@]+}}@no_side_effects +; IS__CGSCC____-SAME: (i8 [[V:%.*]]) +; IS__CGSCC____-NEXT: ret i8* null +; ret i8* null } define internal i8* @dont_zap_me(i8 %v) { -; CHECK-LABEL: define {{[^@]+}}@dont_zap_me -; CHECK-SAME: (i8 [[V:%.*]]) -; CHECK-NEXT: [[I1:%.*]] = call i32 @external() -; CHECK-NEXT: ret i8* undef +; IS__TUNIT____-LABEL: define {{[^@]+}}@dont_zap_me +; IS__TUNIT____-SAME: (i8 [[V:%.*]]) +; IS__TUNIT____-NEXT: [[I1:%.*]] = call i32 @external() +; IS__TUNIT____-NEXT: ret i8* undef +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@dont_zap_me +; IS__CGSCC____-SAME: (i8 [[V:%.*]]) +; IS__CGSCC____-NEXT: [[I1:%.*]] = call i32 @external() +; IS__CGSCC____-NEXT: ret i8* null ; %i1 = call i32 @external() ret i8* null diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/naked-return.ll b/llvm/test/Transforms/Attributor/IPConstantProp/naked-return.ll index 818f299142a5..badb82bd566f 100644 --- a/llvm/test/Transforms/Attributor/IPConstantProp/naked-return.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/naked-return.ll @@ -1,5 +1,8 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=1 < %s | FileCheck %s +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32" target triple = "i686-pc-windows-msvc19.0.24215" diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/openmp_parallel_for.ll b/llvm/test/Transforms/Attributor/IPConstantProp/openmp_parallel_for.ll index 1e662f1f199f..258bb0745b4c 100644 --- a/llvm/test/Transforms/Attributor/IPConstantProp/openmp_parallel_for.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/openmp_parallel_for.ll @@ -1,5 +1,8 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=3 < %s | FileCheck %s +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 ; ; void bar(int, float, double); ; @@ -25,16 +28,49 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" @1 = private unnamed_addr global %struct.ident_t { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds ([23 x i8], [23 x i8]* @.str, i32 0, i32 0) }, align 8 define dso_local void @foo(i32 %N) { -; CHECK-LABEL: define {{[^@]+}}@foo -; CHECK-SAME: (i32 [[N:%.*]]) -; CHECK-NEXT: entry: -; CHECK-NEXT: [[N_ADDR:%.*]] = alloca i32, align 4 -; CHECK-NEXT: [[P:%.*]] = alloca float, align 4 -; CHECK-NEXT: store i32 [[N]], i32* [[N_ADDR]], align 4 -; CHECK-NEXT: store float 3.000000e+00, float* [[P]], align 4 -; CHECK-NEXT: store i32 7, i32* [[N_ADDR]], align 4 -; CHECK-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* nonnull align 8 dereferenceable(24) @1, i32 3, void (i32*, i32*, ...)* nonnull bitcast (void (i32*, i32*, i32*, float*, i64)* @.omp_outlined. to void (i32*, i32*, ...)*), i32* noalias nocapture nonnull readonly align 4 dereferenceable(4) [[N_ADDR]], float* noalias nocapture nonnull readonly align 4 dereferenceable(4) [[P]], i64 undef) -; CHECK-NEXT: ret void +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@foo +; IS__TUNIT_OPM-SAME: (i32 [[N:%.*]]) +; IS__TUNIT_OPM-NEXT: entry: +; IS__TUNIT_OPM-NEXT: [[N_ADDR:%.*]] = alloca i32, align 4 +; IS__TUNIT_OPM-NEXT: [[P:%.*]] = alloca float, align 4 +; IS__TUNIT_OPM-NEXT: store i32 [[N]], i32* [[N_ADDR]], align 4 +; IS__TUNIT_OPM-NEXT: store float 3.000000e+00, float* [[P]], align 4 +; IS__TUNIT_OPM-NEXT: store i32 7, i32* [[N_ADDR]], align 4 +; IS__TUNIT_OPM-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* nonnull align 8 dereferenceable(24) @1, i32 3, void (i32*, i32*, ...)* nonnull bitcast (void (i32*, i32*, i32*, float*, i64)* @.omp_outlined. to void (i32*, i32*, ...)*), i32* nocapture nonnull readonly align 4 dereferenceable(4) [[N_ADDR]], float* nocapture nonnull readonly align 4 dereferenceable(4) [[P]], i64 undef) +; IS__TUNIT_OPM-NEXT: ret void +; +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@foo +; IS__TUNIT_NPM-SAME: (i32 [[N:%.*]]) +; IS__TUNIT_NPM-NEXT: entry: +; IS__TUNIT_NPM-NEXT: [[N_ADDR:%.*]] = alloca i32, align 4 +; IS__TUNIT_NPM-NEXT: [[P:%.*]] = alloca float, align 4 +; IS__TUNIT_NPM-NEXT: store i32 [[N]], i32* [[N_ADDR]], align 4 +; IS__TUNIT_NPM-NEXT: store float 3.000000e+00, float* [[P]], align 4 +; IS__TUNIT_NPM-NEXT: store i32 7, i32* [[N_ADDR]], align 4 +; IS__TUNIT_NPM-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* nonnull align 8 dereferenceable(24) @1, i32 3, void (i32*, i32*, ...)* nonnull bitcast (void (i32*, i32*, i32*, float*, i64)* @.omp_outlined. to void (i32*, i32*, ...)*), i32* noalias nocapture nonnull readonly align 4 dereferenceable(4) [[N_ADDR]], float* noalias nocapture nonnull readonly align 4 dereferenceable(4) [[P]], i64 undef) +; IS__TUNIT_NPM-NEXT: ret void +; +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@foo +; IS__CGSCC_OPM-SAME: (i32 [[N:%.*]]) +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: [[N_ADDR:%.*]] = alloca i32, align 4 +; IS__CGSCC_OPM-NEXT: [[P:%.*]] = alloca float, align 4 +; IS__CGSCC_OPM-NEXT: store i32 [[N]], i32* [[N_ADDR]], align 4 +; IS__CGSCC_OPM-NEXT: store float 3.000000e+00, float* [[P]], align 4 +; IS__CGSCC_OPM-NEXT: store i32 7, i32* [[N_ADDR]], align 4 +; IS__CGSCC_OPM-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* nonnull align 8 dereferenceable(24) @1, i32 3, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, float*, i64)* @.omp_outlined. to void (i32*, i32*, ...)*), i32* nonnull align 4 dereferenceable(4) [[N_ADDR]], float* nonnull align 4 dereferenceable(4) [[P]], i64 4617315517961601024) +; IS__CGSCC_OPM-NEXT: ret void +; +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@foo +; IS__CGSCC_NPM-SAME: (i32 [[N:%.*]]) +; IS__CGSCC_NPM-NEXT: entry: +; IS__CGSCC_NPM-NEXT: [[N_ADDR:%.*]] = alloca i32, align 4 +; IS__CGSCC_NPM-NEXT: [[P:%.*]] = alloca float, align 4 +; IS__CGSCC_NPM-NEXT: store i32 [[N]], i32* [[N_ADDR]], align 4 +; IS__CGSCC_NPM-NEXT: store float 3.000000e+00, float* [[P]], align 4 +; IS__CGSCC_NPM-NEXT: store i32 7, i32* [[N_ADDR]], align 4 +; IS__CGSCC_NPM-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* nonnull align 8 dereferenceable(24) @1, i32 3, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, float*, i64)* @.omp_outlined. to void (i32*, i32*, ...)*), i32* noalias nocapture nonnull readonly align 4 dereferenceable(4) [[N_ADDR]], float* noalias nocapture nonnull readonly align 4 dereferenceable(4) [[P]], i64 4617315517961601024) +; IS__CGSCC_NPM-NEXT: ret void ; entry: %N.addr = alloca i32, align 4 @@ -47,13 +83,195 @@ entry: } define internal void @.omp_outlined.(i32* noalias %.global_tid., i32* noalias %.bound_tid., i32* dereferenceable(4) %N, float* dereferenceable(4) %p, i64 %q) { +; IS________OPM-LABEL: define {{[^@]+}}@.omp_outlined. +; IS________OPM-SAME: (i32* noalias nocapture readonly [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i32* nocapture nonnull readonly align 4 dereferenceable(4) [[N:%.*]], float* nocapture nonnull readonly align 4 dereferenceable(4) [[P:%.*]], i64 [[Q:%.*]]) +; IS________OPM-NEXT: entry: +; IS________OPM-NEXT: [[Q_ADDR:%.*]] = alloca i64, align 8 +; IS________OPM-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +; IS________OPM-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +; IS________OPM-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +; IS________OPM-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +; IS________OPM-NEXT: store i64 4617315517961601024, i64* [[Q_ADDR]], align 8 +; IS________OPM-NEXT: [[CONV:%.*]] = bitcast i64* [[Q_ADDR]] to double* +; IS________OPM-NEXT: [[TMP:%.*]] = load i32, i32* [[N]], align 4 +; IS________OPM-NEXT: [[SUB3:%.*]] = add nsw i32 [[TMP]], -3 +; IS________OPM-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP]], 2 +; IS________OPM-NEXT: br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]] +; IS________OPM: omp.precond.then: +; IS________OPM-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4 +; IS________OPM-NEXT: store i32 [[SUB3]], i32* [[DOTOMP_UB]], align 4 +; IS________OPM-NEXT: store i32 1, i32* [[DOTOMP_STRIDE]], align 4 +; IS________OPM-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4 +; IS________OPM-NEXT: [[TMP5:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4 +; IS________OPM-NEXT: call void @__kmpc_for_static_init_4(%struct.ident_t* nonnull align 8 dereferenceable(24) @0, i32 [[TMP5]], i32 34, i32* nonnull align 4 dereferenceable(4) [[DOTOMP_IS_LAST]], i32* nonnull align 4 dereferenceable(4) [[DOTOMP_LB]], i32* nonnull align 4 dereferenceable(4) [[DOTOMP_UB]], i32* nonnull align 4 dereferenceable(4) [[DOTOMP_STRIDE]], i32 1, i32 1) +; IS________OPM-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4 +; IS________OPM-NEXT: [[CMP6:%.*]] = icmp sgt i32 [[TMP6]], [[SUB3]] +; IS________OPM-NEXT: br i1 [[CMP6]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +; IS________OPM: cond.true: +; IS________OPM-NEXT: br label [[COND_END:%.*]] +; IS________OPM: cond.false: +; IS________OPM-NEXT: [[TMP7:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4 +; IS________OPM-NEXT: br label [[COND_END]] +; IS________OPM: cond.end: +; IS________OPM-NEXT: [[COND:%.*]] = phi i32 [ [[SUB3]], [[COND_TRUE]] ], [ [[TMP7]], [[COND_FALSE]] ] +; IS________OPM-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4 +; IS________OPM-NEXT: [[TMP8:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4 +; IS________OPM-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +; IS________OPM: omp.inner.for.cond: +; IS________OPM-NEXT: [[DOTOMP_IV_0:%.*]] = phi i32 [ [[TMP8]], [[COND_END]] ], [ [[ADD11:%.*]], [[OMP_INNER_FOR_INC:%.*]] ] +; IS________OPM-NEXT: [[TMP9:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4 +; IS________OPM-NEXT: [[CMP8:%.*]] = icmp sgt i32 [[DOTOMP_IV_0]], [[TMP9]] +; IS________OPM-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_COND_CLEANUP:%.*]], label [[OMP_INNER_FOR_BODY:%.*]] +; IS________OPM: omp.inner.for.cond.cleanup: +; IS________OPM-NEXT: br label [[OMP_INNER_FOR_END:%.*]] +; IS________OPM: omp.inner.for.body: +; IS________OPM-NEXT: [[ADD10:%.*]] = add nsw i32 [[DOTOMP_IV_0]], 2 +; IS________OPM-NEXT: [[TMP10:%.*]] = load float, float* [[P]], align 4 +; IS________OPM-NEXT: [[TMP11:%.*]] = load double, double* [[CONV]], align 8 +; IS________OPM-NEXT: call void @bar(i32 [[ADD10]], float [[TMP10]], double [[TMP11]]) +; IS________OPM-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +; IS________OPM: omp.body.continue: +; IS________OPM-NEXT: br label [[OMP_INNER_FOR_INC]] +; IS________OPM: omp.inner.for.inc: +; IS________OPM-NEXT: [[ADD11]] = add nsw i32 [[DOTOMP_IV_0]], 1 +; IS________OPM-NEXT: br label [[OMP_INNER_FOR_COND]] +; IS________OPM: omp.inner.for.end: +; IS________OPM-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +; IS________OPM: omp.loop.exit: +; IS________OPM-NEXT: [[TMP12:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4 +; IS________OPM-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* nonnull align 8 dereferenceable(24) @0, i32 [[TMP12]]) +; IS________OPM-NEXT: br label [[OMP_PRECOND_END]] +; IS________OPM: omp.precond.end: +; IS________OPM-NEXT: ret void +; +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@.omp_outlined. +; IS__TUNIT_NPM-SAME: (i32* noalias nocapture readonly [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i32* noalias nocapture nonnull readonly align 4 dereferenceable(4) [[N:%.*]], float* noalias nocapture nonnull readonly align 4 dereferenceable(4) [[P:%.*]], i64 [[Q:%.*]]) +; IS__TUNIT_NPM-NEXT: entry: +; IS__TUNIT_NPM-NEXT: [[Q_ADDR:%.*]] = alloca i64, align 8 +; IS__TUNIT_NPM-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +; IS__TUNIT_NPM-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +; IS__TUNIT_NPM-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +; IS__TUNIT_NPM-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +; IS__TUNIT_NPM-NEXT: store i64 4617315517961601024, i64* [[Q_ADDR]], align 8 +; IS__TUNIT_NPM-NEXT: [[CONV:%.*]] = bitcast i64* [[Q_ADDR]] to double* +; IS__TUNIT_NPM-NEXT: [[TMP:%.*]] = load i32, i32* [[N]], align 4 +; IS__TUNIT_NPM-NEXT: [[SUB3:%.*]] = add nsw i32 [[TMP]], -3 +; IS__TUNIT_NPM-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP]], 2 +; IS__TUNIT_NPM-NEXT: br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]] +; IS__TUNIT_NPM: omp.precond.then: +; IS__TUNIT_NPM-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4 +; IS__TUNIT_NPM-NEXT: store i32 [[SUB3]], i32* [[DOTOMP_UB]], align 4 +; IS__TUNIT_NPM-NEXT: store i32 1, i32* [[DOTOMP_STRIDE]], align 4 +; IS__TUNIT_NPM-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4 +; IS__TUNIT_NPM-NEXT: [[TMP5:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4 +; IS__TUNIT_NPM-NEXT: call void @__kmpc_for_static_init_4(%struct.ident_t* nonnull align 8 dereferenceable(24) @0, i32 [[TMP5]], i32 34, i32* nonnull align 4 dereferenceable(4) [[DOTOMP_IS_LAST]], i32* nonnull align 4 dereferenceable(4) [[DOTOMP_LB]], i32* nonnull align 4 dereferenceable(4) [[DOTOMP_UB]], i32* nonnull align 4 dereferenceable(4) [[DOTOMP_STRIDE]], i32 1, i32 1) +; IS__TUNIT_NPM-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4 +; IS__TUNIT_NPM-NEXT: [[CMP6:%.*]] = icmp sgt i32 [[TMP6]], [[SUB3]] +; IS__TUNIT_NPM-NEXT: br i1 [[CMP6]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +; IS__TUNIT_NPM: cond.true: +; IS__TUNIT_NPM-NEXT: br label [[COND_END:%.*]] +; IS__TUNIT_NPM: cond.false: +; IS__TUNIT_NPM-NEXT: [[TMP7:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4 +; IS__TUNIT_NPM-NEXT: br label [[COND_END]] +; IS__TUNIT_NPM: cond.end: +; IS__TUNIT_NPM-NEXT: [[COND:%.*]] = phi i32 [ [[SUB3]], [[COND_TRUE]] ], [ [[TMP7]], [[COND_FALSE]] ] +; IS__TUNIT_NPM-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4 +; IS__TUNIT_NPM-NEXT: [[TMP8:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4 +; IS__TUNIT_NPM-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +; IS__TUNIT_NPM: omp.inner.for.cond: +; IS__TUNIT_NPM-NEXT: [[DOTOMP_IV_0:%.*]] = phi i32 [ [[TMP8]], [[COND_END]] ], [ [[ADD11:%.*]], [[OMP_INNER_FOR_INC:%.*]] ] +; IS__TUNIT_NPM-NEXT: [[TMP9:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4 +; IS__TUNIT_NPM-NEXT: [[CMP8:%.*]] = icmp sgt i32 [[DOTOMP_IV_0]], [[TMP9]] +; IS__TUNIT_NPM-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_COND_CLEANUP:%.*]], label [[OMP_INNER_FOR_BODY:%.*]] +; IS__TUNIT_NPM: omp.inner.for.cond.cleanup: +; IS__TUNIT_NPM-NEXT: br label [[OMP_INNER_FOR_END:%.*]] +; IS__TUNIT_NPM: omp.inner.for.body: +; IS__TUNIT_NPM-NEXT: [[ADD10:%.*]] = add nsw i32 [[DOTOMP_IV_0]], 2 +; IS__TUNIT_NPM-NEXT: [[TMP10:%.*]] = load float, float* [[P]], align 4 +; IS__TUNIT_NPM-NEXT: [[TMP11:%.*]] = load double, double* [[CONV]], align 8 +; IS__TUNIT_NPM-NEXT: call void @bar(i32 [[ADD10]], float [[TMP10]], double [[TMP11]]) +; IS__TUNIT_NPM-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +; IS__TUNIT_NPM: omp.body.continue: +; IS__TUNIT_NPM-NEXT: br label [[OMP_INNER_FOR_INC]] +; IS__TUNIT_NPM: omp.inner.for.inc: +; IS__TUNIT_NPM-NEXT: [[ADD11]] = add nsw i32 [[DOTOMP_IV_0]], 1 +; IS__TUNIT_NPM-NEXT: br label [[OMP_INNER_FOR_COND]] +; IS__TUNIT_NPM: omp.inner.for.end: +; IS__TUNIT_NPM-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +; IS__TUNIT_NPM: omp.loop.exit: +; IS__TUNIT_NPM-NEXT: [[TMP12:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4 +; IS__TUNIT_NPM-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* nonnull align 8 dereferenceable(24) @0, i32 [[TMP12]]) +; IS__TUNIT_NPM-NEXT: br label [[OMP_PRECOND_END]] +; IS__TUNIT_NPM: omp.precond.end: +; IS__TUNIT_NPM-NEXT: ret void +; +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@.omp_outlined. +; IS__CGSCC_NPM-SAME: (i32* noalias nocapture readonly [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i32* nocapture nonnull readonly align 4 dereferenceable(4) [[N:%.*]], float* nocapture nonnull readonly dereferenceable(4) [[P:%.*]], i64 [[Q:%.*]]) +; IS__CGSCC_NPM-NEXT: entry: +; IS__CGSCC_NPM-NEXT: [[Q_ADDR:%.*]] = alloca i64, align 8 +; IS__CGSCC_NPM-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +; IS__CGSCC_NPM-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +; IS__CGSCC_NPM-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +; IS__CGSCC_NPM-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +; IS__CGSCC_NPM-NEXT: store i64 4617315517961601024, i64* [[Q_ADDR]], align 8 +; IS__CGSCC_NPM-NEXT: [[CONV:%.*]] = bitcast i64* [[Q_ADDR]] to double* +; IS__CGSCC_NPM-NEXT: [[TMP:%.*]] = load i32, i32* [[N]], align 4 +; IS__CGSCC_NPM-NEXT: [[SUB3:%.*]] = add nsw i32 [[TMP]], -3 +; IS__CGSCC_NPM-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP]], 2 +; IS__CGSCC_NPM-NEXT: br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]] +; IS__CGSCC_NPM: omp.precond.then: +; IS__CGSCC_NPM-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4 +; IS__CGSCC_NPM-NEXT: store i32 [[SUB3]], i32* [[DOTOMP_UB]], align 4 +; IS__CGSCC_NPM-NEXT: store i32 1, i32* [[DOTOMP_STRIDE]], align 4 +; IS__CGSCC_NPM-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4 +; IS__CGSCC_NPM-NEXT: [[TMP5:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4 +; IS__CGSCC_NPM-NEXT: call void @__kmpc_for_static_init_4(%struct.ident_t* nonnull align 8 dereferenceable(24) @0, i32 [[TMP5]], i32 34, i32* nonnull align 4 dereferenceable(4) [[DOTOMP_IS_LAST]], i32* nonnull align 4 dereferenceable(4) [[DOTOMP_LB]], i32* nonnull align 4 dereferenceable(4) [[DOTOMP_UB]], i32* nonnull align 4 dereferenceable(4) [[DOTOMP_STRIDE]], i32 1, i32 1) +; IS__CGSCC_NPM-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4 +; IS__CGSCC_NPM-NEXT: [[CMP6:%.*]] = icmp sgt i32 [[TMP6]], [[SUB3]] +; IS__CGSCC_NPM-NEXT: br i1 [[CMP6]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +; IS__CGSCC_NPM: cond.true: +; IS__CGSCC_NPM-NEXT: br label [[COND_END:%.*]] +; IS__CGSCC_NPM: cond.false: +; IS__CGSCC_NPM-NEXT: [[TMP7:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4 +; IS__CGSCC_NPM-NEXT: br label [[COND_END]] +; IS__CGSCC_NPM: cond.end: +; IS__CGSCC_NPM-NEXT: [[COND:%.*]] = phi i32 [ [[SUB3]], [[COND_TRUE]] ], [ [[TMP7]], [[COND_FALSE]] ] +; IS__CGSCC_NPM-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4 +; IS__CGSCC_NPM-NEXT: [[TMP8:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4 +; IS__CGSCC_NPM-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +; IS__CGSCC_NPM: omp.inner.for.cond: +; IS__CGSCC_NPM-NEXT: [[DOTOMP_IV_0:%.*]] = phi i32 [ [[TMP8]], [[COND_END]] ], [ [[ADD11:%.*]], [[OMP_INNER_FOR_INC:%.*]] ] +; IS__CGSCC_NPM-NEXT: [[TMP9:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4 +; IS__CGSCC_NPM-NEXT: [[CMP8:%.*]] = icmp sgt i32 [[DOTOMP_IV_0]], [[TMP9]] +; IS__CGSCC_NPM-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_COND_CLEANUP:%.*]], label [[OMP_INNER_FOR_BODY:%.*]] +; IS__CGSCC_NPM: omp.inner.for.cond.cleanup: +; IS__CGSCC_NPM-NEXT: br label [[OMP_INNER_FOR_END:%.*]] +; IS__CGSCC_NPM: omp.inner.for.body: +; IS__CGSCC_NPM-NEXT: [[ADD10:%.*]] = add nsw i32 [[DOTOMP_IV_0]], 2 +; IS__CGSCC_NPM-NEXT: [[TMP10:%.*]] = load float, float* [[P]], align 4 +; IS__CGSCC_NPM-NEXT: [[TMP11:%.*]] = load double, double* [[CONV]], align 8 +; IS__CGSCC_NPM-NEXT: call void @bar(i32 [[ADD10]], float [[TMP10]], double [[TMP11]]) +; IS__CGSCC_NPM-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +; IS__CGSCC_NPM: omp.body.continue: +; IS__CGSCC_NPM-NEXT: br label [[OMP_INNER_FOR_INC]] +; IS__CGSCC_NPM: omp.inner.for.inc: +; IS__CGSCC_NPM-NEXT: [[ADD11]] = add nsw i32 [[DOTOMP_IV_0]], 1 +; IS__CGSCC_NPM-NEXT: br label [[OMP_INNER_FOR_COND]] +; IS__CGSCC_NPM: omp.inner.for.end: +; IS__CGSCC_NPM-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +; IS__CGSCC_NPM: omp.loop.exit: +; IS__CGSCC_NPM-NEXT: [[TMP12:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4 +; IS__CGSCC_NPM-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* nonnull align 8 dereferenceable(24) @0, i32 [[TMP12]]) +; IS__CGSCC_NPM-NEXT: br label [[OMP_PRECOND_END]] +; IS__CGSCC_NPM: omp.precond.end: +; IS__CGSCC_NPM-NEXT: ret void +; entry: %q.addr = alloca i64, align 8 %.omp.lb = alloca i32, align 4 %.omp.ub = alloca i32, align 4 %.omp.stride = alloca i32, align 4 %.omp.is_last = alloca i32, align 4 -; CHECK: store i64 4617315517961601024, i64* %q.addr, align 8 store i64 %q, i64* %q.addr, align 8 %conv = bitcast i64* %q.addr to double* %tmp = load i32, i32* %N, align 4 diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/pthreads.ll b/llvm/test/Transforms/Attributor/IPConstantProp/pthreads.ll index 12fb1234c9c6..4399f3a37a8b 100644 --- a/llvm/test/Transforms/Attributor/IPConstantProp/pthreads.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/pthreads.ll @@ -1,6 +1,8 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=1 < %s | FileCheck %s --check-prefixes=CHECK,MODULE -; RUN: opt -S -passes=attributor-cgscc -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=1 < %s | FileCheck %s --check-prefixes=CHECK,CGSCC +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 ; ; #include ; @@ -29,27 +31,38 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" ; FIXME: nocapture & noalias for %alloc2 in %call3 define dso_local i32 @main() { -; MODULE-LABEL: define {{[^@]+}}@main() -; MODULE-NEXT: entry: -; MODULE-NEXT: [[ALLOC1:%.*]] = alloca i8, align 8 -; MODULE-NEXT: [[ALLOC2:%.*]] = alloca i8, align 8 -; MODULE-NEXT: [[THREAD:%.*]] = alloca i64, align 8 -; MODULE-NEXT: [[CALL:%.*]] = call i32 @pthread_create(i64* nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias align 536870912 null, i8* (i8*)* nonnull @foo, i8* noalias nofree readnone align 536870912 undef) -; MODULE-NEXT: [[CALL1:%.*]] = call i32 @pthread_create(i64* nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias align 536870912 null, i8* (i8*)* nonnull @bar, i8* noalias nofree nonnull readnone align 8 dereferenceable(8) undef) -; MODULE-NEXT: [[CALL2:%.*]] = call i32 @pthread_create(i64* nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias align 536870912 null, i8* (i8*)* nonnull @baz, i8* noalias nocapture nofree nonnull readnone align 8 dereferenceable(1) [[ALLOC1]]) -; MODULE-NEXT: [[CALL3:%.*]] = call i32 @pthread_create(i64* nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias align 536870912 null, i8* (i8*)* nonnull @buz, i8* noalias nofree nonnull readnone align 8 dereferenceable(1) [[ALLOC2]]) -; MODULE-NEXT: ret i32 0 +; IS__TUNIT____-LABEL: define {{[^@]+}}@main() +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: [[ALLOC1:%.*]] = alloca i8, align 8 +; IS__TUNIT____-NEXT: [[ALLOC2:%.*]] = alloca i8, align 8 +; IS__TUNIT____-NEXT: [[THREAD:%.*]] = alloca i64, align 8 +; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32 @pthread_create(i64* nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias align 536870912 null, i8* (i8*)* nonnull @foo, i8* noalias nofree readnone align 536870912 undef) +; IS__TUNIT____-NEXT: [[CALL1:%.*]] = call i32 @pthread_create(i64* nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias align 536870912 null, i8* (i8*)* nonnull @bar, i8* noalias nofree nonnull readnone align 8 dereferenceable(8) undef) +; IS__TUNIT____-NEXT: [[CALL2:%.*]] = call i32 @pthread_create(i64* nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias align 536870912 null, i8* (i8*)* nonnull @baz, i8* noalias nocapture nofree nonnull readnone align 8 dereferenceable(1) [[ALLOC1]]) +; IS__TUNIT____-NEXT: [[CALL3:%.*]] = call i32 @pthread_create(i64* nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias align 536870912 null, i8* (i8*)* nonnull @buz, i8* noalias nofree nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" [[ALLOC2]]) +; IS__TUNIT____-NEXT: ret i32 0 ; -; CGSCC-LABEL: define {{[^@]+}}@main() -; CGSCC-NEXT: entry: -; CGSCC-NEXT: [[ALLOC1:%.*]] = alloca i8, align 8 -; CGSCC-NEXT: [[ALLOC2:%.*]] = alloca i8, align 8 -; CGSCC-NEXT: [[THREAD:%.*]] = alloca i64, align 8 -; CGSCC-NEXT: [[CALL:%.*]] = call i32 @pthread_create(i64* nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias align 536870912 null, i8* (i8*)* nonnull @foo, i8* noalias nofree readnone align 536870912 null) -; CGSCC-NEXT: [[CALL1:%.*]] = call i32 @pthread_create(i64* nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias align 536870912 null, i8* (i8*)* nonnull @bar, i8* noalias nofree nonnull readnone align 8 dereferenceable(8) bitcast (i8** @GlobalVPtr to i8*)) -; CGSCC-NEXT: [[CALL2:%.*]] = call i32 @pthread_create(i64* nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias align 536870912 null, i8* (i8*)* nonnull @baz, i8* noalias nocapture nofree nonnull readnone align 8 dereferenceable(1) [[ALLOC1]]) -; CGSCC-NEXT: [[CALL3:%.*]] = call i32 @pthread_create(i64* nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias align 536870912 null, i8* (i8*)* nonnull @buz, i8* noalias nofree nonnull readnone align 8 dereferenceable(1) [[ALLOC2]]) -; CGSCC-NEXT: ret i32 0 +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@main() +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: [[ALLOC1:%.*]] = alloca i8, align 8 +; IS__CGSCC_OPM-NEXT: [[ALLOC2:%.*]] = alloca i8, align 8 +; IS__CGSCC_OPM-NEXT: [[THREAD:%.*]] = alloca i64, align 8 +; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call i32 @pthread_create(i64* nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias align 536870912 null, i8* (i8*)* nonnull @foo, i8* noalias align 536870912 null) +; IS__CGSCC_OPM-NEXT: [[CALL1:%.*]] = call i32 @pthread_create(i64* nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias align 536870912 null, i8* (i8*)* nonnull @bar, i8* nonnull align 8 dereferenceable(8) bitcast (i8** @GlobalVPtr to i8*)) +; IS__CGSCC_OPM-NEXT: [[CALL2:%.*]] = call i32 @pthread_create(i64* nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias align 536870912 null, i8* (i8*)* nonnull @baz, i8* nocapture nonnull align 8 dereferenceable(1) [[ALLOC1]]) +; IS__CGSCC_OPM-NEXT: [[CALL3:%.*]] = call i32 @pthread_create(i64* nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias align 536870912 null, i8* (i8*)* nonnull @buz, i8* nonnull align 8 dereferenceable(1) [[ALLOC2]]) +; IS__CGSCC_OPM-NEXT: ret i32 0 +; +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@main() +; IS__CGSCC_NPM-NEXT: entry: +; IS__CGSCC_NPM-NEXT: [[ALLOC1:%.*]] = alloca i8, align 8 +; IS__CGSCC_NPM-NEXT: [[ALLOC2:%.*]] = alloca i8, align 8 +; IS__CGSCC_NPM-NEXT: [[THREAD:%.*]] = alloca i64, align 8 +; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call i32 @pthread_create(i64* nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias align 536870912 null, i8* (i8*)* nonnull @foo, i8* noalias nofree readnone align 536870912 null) +; IS__CGSCC_NPM-NEXT: [[CALL1:%.*]] = call i32 @pthread_create(i64* nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias align 536870912 null, i8* (i8*)* nonnull @bar, i8* noalias nofree nonnull readnone align 8 dereferenceable(8) bitcast (i8** @GlobalVPtr to i8*)) +; IS__CGSCC_NPM-NEXT: [[CALL2:%.*]] = call i32 @pthread_create(i64* nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias align 536870912 null, i8* (i8*)* nonnull @baz, i8* noalias nocapture nofree nonnull readnone align 8 dereferenceable(1) [[ALLOC1]]) +; IS__CGSCC_NPM-NEXT: [[CALL3:%.*]] = call i32 @pthread_create(i64* nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias align 536870912 null, i8* (i8*)* nonnull @buz, i8* noalias nofree nonnull readnone align 8 dereferenceable(1) [[ALLOC2]]) +; IS__CGSCC_NPM-NEXT: ret i32 0 ; entry: %alloc1 = alloca i8, align 8 @@ -65,60 +78,75 @@ entry: declare !callback !0 dso_local i32 @pthread_create(i64*, %union.pthread_attr_t*, i8* (i8*)*, i8*) define internal i8* @foo(i8* %arg) { -; MODULE-LABEL: define {{[^@]+}}@foo -; MODULE-SAME: (i8* noalias nofree readnone returned align 536870912 [[ARG:%.*]]) -; MODULE-NEXT: entry: -; MODULE-NEXT: ret i8* null +; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@foo +; NOT_CGSCC_NPM-SAME: (i8* noalias nofree readnone returned align 536870912 "no-capture-maybe-returned" [[ARG:%.*]]) +; NOT_CGSCC_NPM-NEXT: entry: +; NOT_CGSCC_NPM-NEXT: ret i8* null ; -; CGSCC-LABEL: define {{[^@]+}}@foo -; CGSCC-SAME: (i8* noalias nofree readnone returned [[ARG:%.*]]) -; CGSCC-NEXT: entry: -; CGSCC-NEXT: ret i8* null +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@foo +; IS__CGSCC_NPM-SAME: (i8* noalias nofree readnone returned "no-capture-maybe-returned" [[ARG:%.*]]) +; IS__CGSCC_NPM-NEXT: entry: +; IS__CGSCC_NPM-NEXT: ret i8* null ; entry: ret i8* %arg } define internal i8* @bar(i8* %arg) { -; MODULE-LABEL: define {{[^@]+}}@bar -; MODULE-SAME: (i8* noalias nofree nonnull readnone returned align 8 dereferenceable(8) [[ARG:%.*]]) -; MODULE-NEXT: entry: -; MODULE-NEXT: ret i8* bitcast (i8** @GlobalVPtr to i8*) +; IS__TUNIT____-LABEL: define {{[^@]+}}@bar +; IS__TUNIT____-SAME: (i8* noalias nofree nonnull readnone returned align 8 dereferenceable(8) "no-capture-maybe-returned" [[ARG:%.*]]) +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: ret i8* bitcast (i8** @GlobalVPtr to i8*) ; -; CGSCC-LABEL: define {{[^@]+}}@bar -; CGSCC-SAME: (i8* nofree readnone returned [[ARG:%.*]]) -; CGSCC-NEXT: entry: -; CGSCC-NEXT: ret i8* bitcast (i8** @GlobalVPtr to i8*) +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@bar +; IS__CGSCC_OPM-SAME: (i8* nofree nonnull readnone returned align 8 dereferenceable(8) "no-capture-maybe-returned" [[ARG:%.*]]) +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: ret i8* bitcast (i8** @GlobalVPtr to i8*) +; +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@bar +; IS__CGSCC_NPM-SAME: (i8* nofree readnone returned "no-capture-maybe-returned" [[ARG:%.*]]) +; IS__CGSCC_NPM-NEXT: entry: +; IS__CGSCC_NPM-NEXT: ret i8* bitcast (i8** @GlobalVPtr to i8*) ; entry: ret i8* %arg } define internal i8* @baz(i8* %arg) { -; MODULE-LABEL: define {{[^@]+}}@baz -; MODULE-SAME: (i8* noalias nofree nonnull readnone returned align 8 dereferenceable(1) [[ARG:%.*]]) -; MODULE-NEXT: entry: -; MODULE-NEXT: ret i8* [[ARG]] +; IS__TUNIT____-LABEL: define {{[^@]+}}@baz +; IS__TUNIT____-SAME: (i8* noalias nofree nonnull readnone returned align 8 dereferenceable(1) "no-capture-maybe-returned" [[ARG:%.*]]) +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: ret i8* [[ARG]] ; -; CGSCC-LABEL: define {{[^@]+}}@baz -; CGSCC-SAME: (i8* nofree readnone returned [[ARG:%.*]]) -; CGSCC-NEXT: entry: -; CGSCC-NEXT: ret i8* [[ARG]] +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@baz +; IS__CGSCC_OPM-SAME: (i8* nofree nonnull readnone returned align 8 dereferenceable(1) "no-capture-maybe-returned" [[ARG:%.*]]) +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: ret i8* [[ARG]] +; +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@baz +; IS__CGSCC_NPM-SAME: (i8* nofree readnone returned "no-capture-maybe-returned" [[ARG:%.*]]) +; IS__CGSCC_NPM-NEXT: entry: +; IS__CGSCC_NPM-NEXT: ret i8* [[ARG]] ; entry: ret i8* %arg } define internal i8* @buz(i8* %arg) { -; MODULE-LABEL: define {{[^@]+}}@buz -; MODULE-SAME: (i8* noalias nofree nonnull readnone returned align 8 dereferenceable(1) [[ARG:%.*]]) -; MODULE-NEXT: entry: -; MODULE-NEXT: ret i8* [[ARG]] +; IS__TUNIT____-LABEL: define {{[^@]+}}@buz +; IS__TUNIT____-SAME: (i8* noalias nofree nonnull readnone returned align 8 dereferenceable(1) "no-capture-maybe-returned" [[ARG:%.*]]) +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: ret i8* [[ARG]] ; -; CGSCC-LABEL: define {{[^@]+}}@buz -; CGSCC-SAME: (i8* nofree readnone returned [[ARG:%.*]]) -; CGSCC-NEXT: entry: -; CGSCC-NEXT: ret i8* [[ARG]] +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@buz +; IS__CGSCC_OPM-SAME: (i8* nofree nonnull readnone returned align 8 dereferenceable(1) "no-capture-maybe-returned" [[ARG:%.*]]) +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: ret i8* [[ARG]] +; +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@buz +; IS__CGSCC_NPM-SAME: (i8* nofree readnone returned "no-capture-maybe-returned" [[ARG:%.*]]) +; IS__CGSCC_NPM-NEXT: entry: +; IS__CGSCC_NPM-NEXT: ret i8* [[ARG]] ; entry: ret i8* %arg diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/recursion.ll b/llvm/test/Transforms/Attributor/IPConstantProp/recursion.ll index 831c0c6ebb98..1351d3117853 100644 --- a/llvm/test/Transforms/Attributor/IPConstantProp/recursion.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/recursion.ll @@ -1,9 +1,15 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=1 < %s | FileCheck %s +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 ; CHECK-NOT: %X define internal i32 @foo(i32 %X) { +; IS__CGSCC____-LABEL: define {{[^@]+}}@foo() +; IS__CGSCC____-NEXT: unreachable +; %Y = call i32 @foo( i32 %X ) ; [#uses=1] %Z = add i32 %Y, 1 ; [#uses=1] ret i32 %Z diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/remove-call-inst.ll b/llvm/test/Transforms/Attributor/IPConstantProp/remove-call-inst.ll index 9420f53980cb..5b11512f9b6d 100644 --- a/llvm/test/Transforms/Attributor/IPConstantProp/remove-call-inst.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/remove-call-inst.ll @@ -1,5 +1,8 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=1 < %s | FileCheck %s +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 ; PR5596 ; IPSCCP should propagate the 0 argument, eliminate the switch, and propagate @@ -18,6 +21,17 @@ entry: } define internal i32 @wwrite(i64 %i) nounwind readnone { +; IS__CGSCC____-LABEL: define {{[^@]+}}@wwrite() +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: switch i64 0, label [[SW_DEFAULT:%.*]] [ +; IS__CGSCC____-NEXT: i64 3, label [[RETURN:%.*]] +; IS__CGSCC____-NEXT: i64 10, label [[RETURN]] +; IS__CGSCC____-NEXT: ] +; IS__CGSCC____: sw.default: +; IS__CGSCC____-NEXT: ret i32 123 +; IS__CGSCC____: return: +; IS__CGSCC____-NEXT: unreachable +; entry: switch i64 %i, label %sw.default [ i64 3, label %return diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/return-argument.ll b/llvm/test/Transforms/Attributor/IPConstantProp/return-argument.ll index 05b0107a3bb4..80c0ba7b5fb7 100644 --- a/llvm/test/Transforms/Attributor/IPConstantProp/return-argument.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/return-argument.ll @@ -1,20 +1,36 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=8 < %s | FileCheck %s +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=8 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=8 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 ;; This function returns its second argument on all return statements define internal i32* @incdec(i1 %C, i32* %V) { -; CHECK-LABEL: define {{[^@]+}}@incdec -; CHECK-SAME: (i1 [[C:%.*]], i32* noalias nofree nonnull returned align 4 dereferenceable(4) [[V:%.*]]) -; CHECK-NEXT: [[X:%.*]] = load i32, i32* [[V]], align 4 -; CHECK-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] -; CHECK: T: -; CHECK-NEXT: [[X1:%.*]] = add i32 [[X]], 1 -; CHECK-NEXT: store i32 [[X1]], i32* [[V]], align 4 -; CHECK-NEXT: ret i32* [[V]] -; CHECK: F: -; CHECK-NEXT: [[X2:%.*]] = sub i32 [[X]], 1 -; CHECK-NEXT: store i32 [[X2]], i32* [[V]], align 4 -; CHECK-NEXT: ret i32* [[V]] +; IS__TUNIT____-LABEL: define {{[^@]+}}@incdec +; IS__TUNIT____-SAME: (i1 [[C:%.*]], i32* noalias nofree nonnull returned align 4 dereferenceable(4) "no-capture-maybe-returned" [[V:%.*]]) +; IS__TUNIT____-NEXT: [[X:%.*]] = load i32, i32* [[V]], align 4 +; IS__TUNIT____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] +; IS__TUNIT____: T: +; IS__TUNIT____-NEXT: [[X1:%.*]] = add i32 [[X]], 1 +; IS__TUNIT____-NEXT: store i32 [[X1]], i32* [[V]], align 4 +; IS__TUNIT____-NEXT: ret i32* [[V]] +; IS__TUNIT____: F: +; IS__TUNIT____-NEXT: [[X2:%.*]] = sub i32 [[X]], 1 +; IS__TUNIT____-NEXT: store i32 [[X2]], i32* [[V]], align 4 +; IS__TUNIT____-NEXT: ret i32* [[V]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@incdec +; IS__CGSCC____-SAME: (i1 [[C:%.*]], i32* nofree nonnull returned align 4 dereferenceable(4) "no-capture-maybe-returned" [[V:%.*]]) +; IS__CGSCC____-NEXT: [[X:%.*]] = load i32, i32* [[V]], align 4 +; IS__CGSCC____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] +; IS__CGSCC____: T: +; IS__CGSCC____-NEXT: [[X1:%.*]] = add i32 [[X]], 1 +; IS__CGSCC____-NEXT: store i32 [[X1]], i32* [[V]], align 4 +; IS__CGSCC____-NEXT: ret i32* [[V]] +; IS__CGSCC____: F: +; IS__CGSCC____-NEXT: [[X2:%.*]] = sub i32 [[X]], 1 +; IS__CGSCC____-NEXT: store i32 [[X2]], i32* [[V]], align 4 +; IS__CGSCC____-NEXT: ret i32* [[V]] ; %X = load i32, i32* %V br i1 %C, label %T, label %F @@ -47,25 +63,43 @@ define internal { i32, i32 } @foo(i32 %A, i32 %B) { } define void @caller(i1 %C) personality i32 (...)* @__gxx_personality_v0 { -; CHECK-LABEL: define {{[^@]+}}@caller -; CHECK-SAME: (i1 [[C:%.*]]) #2 personality i32 (...)* @__gxx_personality_v0 -; CHECK-NEXT: [[Q:%.*]] = alloca i32 -; CHECK-NEXT: [[W:%.*]] = call align 4 i32* @incdec(i1 [[C]], i32* noalias nofree nonnull align 4 dereferenceable(4) [[Q]]) -; CHECK-NEXT: [[S1:%.*]] = call { i32, i32 } @foo(i32 1, i32 2) -; CHECK-NEXT: [[X1:%.*]] = extractvalue { i32, i32 } [[S1]], 0 -; CHECK-NEXT: [[S2:%.*]] = invoke { i32, i32 } @foo(i32 3, i32 4) -; CHECK-NEXT: to label [[OK:%.*]] unwind label [[LPAD:%.*]] -; CHECK: OK: -; CHECK-NEXT: [[X2:%.*]] = extractvalue { i32, i32 } [[S2]], 0 -; CHECK-NEXT: [[Z:%.*]] = add i32 [[X1]], [[X2]] -; CHECK-NEXT: store i32 [[Z]], i32* [[W]], align 4 -; CHECK-NEXT: br label [[RET:%.*]] -; CHECK: LPAD: -; CHECK-NEXT: [[EXN:%.*]] = landingpad { i8*, i32 } -; CHECK-NEXT: cleanup -; CHECK-NEXT: br label [[RET]] -; CHECK: RET: -; CHECK-NEXT: ret void +; IS__TUNIT____-LABEL: define {{[^@]+}}@caller +; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #2 personality i32 (...)* @__gxx_personality_v0 +; IS__TUNIT____-NEXT: [[Q:%.*]] = alloca i32 +; IS__TUNIT____-NEXT: [[W:%.*]] = call align 4 i32* @incdec(i1 [[C]], i32* noalias nofree nonnull align 4 dereferenceable(4) "no-capture-maybe-returned" [[Q]]) +; IS__TUNIT____-NEXT: [[S1:%.*]] = call { i32, i32 } @foo(i32 1, i32 2) +; IS__TUNIT____-NEXT: [[X1:%.*]] = extractvalue { i32, i32 } [[S1]], 0 +; IS__TUNIT____-NEXT: [[S2:%.*]] = invoke { i32, i32 } @foo(i32 3, i32 4) +; IS__TUNIT____-NEXT: to label [[OK:%.*]] unwind label [[LPAD:%.*]] +; IS__TUNIT____: OK: +; IS__TUNIT____-NEXT: [[X2:%.*]] = extractvalue { i32, i32 } [[S2]], 0 +; IS__TUNIT____-NEXT: [[Z:%.*]] = add i32 [[X1]], [[X2]] +; IS__TUNIT____-NEXT: store i32 [[Z]], i32* [[W]], align 4 +; IS__TUNIT____-NEXT: br label [[RET:%.*]] +; IS__TUNIT____: LPAD: +; IS__TUNIT____-NEXT: [[EXN:%.*]] = landingpad { i8*, i32 } +; IS__TUNIT____-NEXT: cleanup +; IS__TUNIT____-NEXT: br label [[RET]] +; IS__TUNIT____: RET: +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@caller +; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #1 personality i32 (...)* @__gxx_personality_v0 +; IS__CGSCC____-NEXT: [[Q:%.*]] = alloca i32 +; IS__CGSCC____-NEXT: [[W:%.*]] = call align 4 i32* @incdec(i1 [[C]], i32* noalias nofree nonnull align 4 dereferenceable(4) [[Q]]) +; IS__CGSCC____-NEXT: [[S1:%.*]] = call { i32, i32 } @foo(i32 1, i32 2) +; IS__CGSCC____-NEXT: [[X1:%.*]] = extractvalue { i32, i32 } [[S1]], 0 +; IS__CGSCC____-NEXT: [[S2:%.*]] = call { i32, i32 } @foo(i32 3, i32 4) +; IS__CGSCC____-NEXT: br label [[OK:%.*]] +; IS__CGSCC____: OK: +; IS__CGSCC____-NEXT: [[X2:%.*]] = extractvalue { i32, i32 } [[S2]], 0 +; IS__CGSCC____-NEXT: [[Z:%.*]] = add i32 [[X1]], [[X2]] +; IS__CGSCC____-NEXT: store i32 [[Z]], i32* [[W]], align 4 +; IS__CGSCC____-NEXT: br label [[RET:%.*]] +; IS__CGSCC____: LPAD: +; IS__CGSCC____-NEXT: unreachable +; IS__CGSCC____: RET: +; IS__CGSCC____-NEXT: ret void ; %Q = alloca i32 ;; Call incdec to see if %W is properly replaced by %Q diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/return-constant.ll b/llvm/test/Transforms/Attributor/IPConstantProp/return-constant.ll index 1810b07e7549..d7c5e9278a81 100644 --- a/llvm/test/Transforms/Attributor/IPConstantProp/return-constant.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/return-constant.ll @@ -1,5 +1,8 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=1 < %s | FileCheck %s +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 ; FIXME: icmp folding is missing @@ -24,13 +27,21 @@ FAIL: } define internal i32 @foo(i1 %C) { -; CHECK-LABEL: define {{[^@]+}}@foo -; CHECK-SAME: (i1 [[C:%.*]]) -; CHECK-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] -; CHECK: T: -; CHECK-NEXT: ret i32 undef -; CHECK: F: -; CHECK-NEXT: ret i32 undef +; IS__TUNIT____-LABEL: define {{[^@]+}}@foo +; IS__TUNIT____-SAME: (i1 [[C:%.*]]) +; IS__TUNIT____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] +; IS__TUNIT____: T: +; IS__TUNIT____-NEXT: ret i32 undef +; IS__TUNIT____: F: +; IS__TUNIT____-NEXT: ret i32 undef +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@foo +; IS__CGSCC____-SAME: (i1 [[C:%.*]]) +; IS__CGSCC____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] +; IS__CGSCC____: T: +; IS__CGSCC____-NEXT: ret i32 52 +; IS__CGSCC____: F: +; IS__CGSCC____-NEXT: ret i32 52 ; br i1 %C, label %T, label %F diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/return-constants.ll b/llvm/test/Transforms/Attributor/IPConstantProp/return-constants.ll index d53b11b4fc4c..51d94f7be855 100644 --- a/llvm/test/Transforms/Attributor/IPConstantProp/return-constants.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/return-constants.ll @@ -1,5 +1,8 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=7 < %s | FileCheck %s +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=7 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=7 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 ;; FIXME: support for extractvalue and insertvalue missing. diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/solve-after-each-resolving-undefs-for-function.ll b/llvm/test/Transforms/Attributor/IPConstantProp/solve-after-each-resolving-undefs-for-function.ll index b5663c9c8c13..6ed063662dfa 100644 --- a/llvm/test/Transforms/Attributor/IPConstantProp/solve-after-each-resolving-undefs-for-function.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/solve-after-each-resolving-undefs-for-function.ll @@ -1,7 +1,21 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=1 < %s | FileCheck %s +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 define internal i32 @testf(i1 %c) { +; IS__CGSCC____-LABEL: define {{[^@]+}}@testf +; IS__CGSCC____-SAME: (i1 [[C:%.*]]) +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: br i1 [[C]], label [[IF_COND:%.*]], label [[IF_END:%.*]] +; IS__CGSCC____: if.cond: +; IS__CGSCC____-NEXT: unreachable +; IS__CGSCC____: if.then: +; IS__CGSCC____-NEXT: unreachable +; IS__CGSCC____: if.end: +; IS__CGSCC____-NEXT: ret i32 10 +; entry: br i1 %c, label %if.cond, label %if.end @@ -16,6 +30,17 @@ if.end: ; preds = %if.then1, %entry } define internal i32 @test1(i1 %c) { +; IS__CGSCC____-LABEL: define {{[^@]+}}@test1 +; IS__CGSCC____-SAME: (i1 [[C:%.*]]) +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: br label [[IF_THEN:%.*]] +; IS__CGSCC____: if.then: +; IS__CGSCC____-NEXT: br label [[RET1:%.*]] +; IS__CGSCC____: ret1: +; IS__CGSCC____-NEXT: ret i32 99 +; IS__CGSCC____: ret2: +; IS__CGSCC____-NEXT: unreachable +; entry: br label %if.then diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/thread_local_acs.ll b/llvm/test/Transforms/Attributor/IPConstantProp/thread_local_acs.ll index 3c11e799b3d2..10e2ac8006d5 100644 --- a/llvm/test/Transforms/Attributor/IPConstantProp/thread_local_acs.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/thread_local_acs.ll @@ -1,5 +1,8 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=1 < %s | FileCheck %s +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 ; ; #include ; thread_local int gtl = 0; @@ -37,10 +40,15 @@ entry: } define dso_local void @caller() { -; CHECK-LABEL: define {{[^@]+}}@caller() -; CHECK-NEXT: entry: -; CHECK-NEXT: call void @broker(i32* nofree nonnull readonly align 4 dereferenceable(4) @gtl, i32 (i32*, i32*)* nonnull @callee, i32* nofree nonnull readonly align 4 dereferenceable(4) undef) -; CHECK-NEXT: ret void +; IS__TUNIT____-LABEL: define {{[^@]+}}@caller() +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: call void @broker(i32* nofree nonnull readonly align 4 dereferenceable(4) @gtl, i32 (i32*, i32*)* nonnull @callee, i32* nofree nonnull readonly align 4 dereferenceable(4) undef) +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@caller() +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: call void @broker(i32* nofree nonnull readonly align 4 dereferenceable(4) @gtl, i32 (i32*, i32*)* nonnull @callee, i32* nofree nonnull readonly align 4 dereferenceable(4) @gsh) +; IS__CGSCC____-NEXT: ret void ; entry: call void @broker(i32* nonnull @gtl, i32 (i32*, i32*)* nonnull @callee, i32* nonnull @gsh) diff --git a/llvm/test/Transforms/Attributor/align.ll b/llvm/test/Transforms/Attributor/align.ll index 882d0e8b8c7f..88d070fb8768 100644 --- a/llvm/test/Transforms/Attributor/align.ll +++ b/llvm/test/Transforms/Attributor/align.ll @@ -1,8 +1,8 @@ -; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --disable --function-signature --scrub-attributes -; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=6 -S < %s | FileCheck %s --check-prefixes=ATTRIBUTOR,ATTRIBUTOR_MODULE -; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-disable=false -attributor-annotate-decl-cs -attributor-max-iterations=6 -S < %s | FileCheck %s --check-prefixes=ATTRIBUTOR,ATTRIBUTOR_CGSCC -; RUN: opt -passes=attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=6 -S < %s | FileCheck %s --check-prefixes=ATTRIBUTOR,ATTRIBUTOR_MODULE -; RUN: opt -passes=attributor-cgscc -attributor-manifest-internal -attributor-disable=false -attributor-annotate-decl-cs -attributor-max-iterations=6 -S < %s | FileCheck %s --check-prefixes=ATTRIBUTOR,ATTRIBUTOR_CGSCC +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=6 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=6 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" @@ -11,27 +11,41 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" ; TEST 1 -; ATTRIBUTOR: define align 8 i32* @test1(i32* nofree readnone returned align 8 "no-capture-maybe-returned" %0) define i32* @test1(i32* align 8 %0) #0 { +; CHECK-LABEL: define {{[^@]+}}@test1 +; CHECK-SAME: (i32* nofree readnone returned align 8 "no-capture-maybe-returned" [[TMP0:%.*]]) +; CHECK-NEXT: ret i32* [[TMP0]] +; ret i32* %0 } ; TEST 2 -; ATTRIBUTOR: define i32* @test2(i32* nofree readnone returned "no-capture-maybe-returned" %0) define i32* @test2(i32* %0) #0 { +; CHECK-LABEL: define {{[^@]+}}@test2 +; CHECK-SAME: (i32* nofree readnone returned "no-capture-maybe-returned" [[TMP0:%.*]]) +; CHECK-NEXT: ret i32* [[TMP0]] +; ret i32* %0 } ; TEST 3 -; ATTRIBUTOR: define align 4 i32* @test3(i32* nofree readnone align 8 "no-capture-maybe-returned" %0, i32* nofree readnone align 4 "no-capture-maybe-returned" %1, i1 %2) define i32* @test3(i32* align 8 %0, i32* align 4 %1, i1 %2) #0 { +; CHECK-LABEL: define {{[^@]+}}@test3 +; CHECK-SAME: (i32* nofree readnone align 8 "no-capture-maybe-returned" [[TMP0:%.*]], i32* nofree readnone align 4 "no-capture-maybe-returned" [[TMP1:%.*]], i1 [[TMP2:%.*]]) +; CHECK-NEXT: [[RET:%.*]] = select i1 [[TMP2]], i32* [[TMP0]], i32* [[TMP1]] +; CHECK-NEXT: ret i32* [[RET]] +; %ret = select i1 %2, i32* %0, i32* %1 ret i32* %ret } ; TEST 4 -; ATTRIBUTOR: define align 32 i32* @test4(i32* nofree readnone align 32 "no-capture-maybe-returned" %0, i32* nofree readnone align 32 "no-capture-maybe-returned" %1, i1 %2) define i32* @test4(i32* align 32 %0, i32* align 32 %1, i1 %2) #0 { +; CHECK-LABEL: define {{[^@]+}}@test4 +; CHECK-SAME: (i32* nofree readnone align 32 "no-capture-maybe-returned" [[TMP0:%.*]], i32* nofree readnone align 32 "no-capture-maybe-returned" [[TMP1:%.*]], i1 [[TMP2:%.*]]) +; CHECK-NEXT: [[RET:%.*]] = select i1 [[TMP2]], i32* [[TMP0]], i32* [[TMP1]] +; CHECK-NEXT: ret i32* [[RET]] +; %ret = select i1 %2, i32* %0, i32* %1 ret i32* %ret } @@ -41,28 +55,38 @@ declare i32* @unknown() declare align 8 i32* @align8() -; ATTRIBUTOR: define align 8 i32* @test5_1() define i32* @test5_1() { +; CHECK-LABEL: define {{[^@]+}}@test5_1() +; CHECK-NEXT: [[RET:%.*]] = tail call align 8 i32* @unknown() +; CHECK-NEXT: ret i32* [[RET]] +; %ret = tail call align 8 i32* @unknown() ret i32* %ret } -; ATTRIBUTOR: define align 8 i32* @test5_2() define i32* @test5_2() { +; CHECK-LABEL: define {{[^@]+}}@test5_2() +; CHECK-NEXT: [[RET:%.*]] = tail call align 8 i32* @align8() +; CHECK-NEXT: ret i32* [[RET]] +; %ret = tail call i32* @align8() ret i32* %ret } ; TEST 6 ; SCC -; ATTRIBUTOR: define noalias nonnull align 536870912 dereferenceable(4294967295) i32* @test6_1() define i32* @test6_1() #0 { +; CHECK-LABEL: define {{[^@]+}}@test6_1() +; CHECK-NEXT: unreachable +; %ret = tail call i32* @test6_2() ret i32* %ret } -; ATTRIBUTOR: define noalias nonnull align 536870912 dereferenceable(4294967295) i32* @test6_2() define i32* @test6_2() #0 { +; CHECK-LABEL: define {{[^@]+}}@test6_2() +; CHECK-NEXT: unreachable +; %ret = tail call i32* @test6_1() ret i32* %ret } @@ -87,6 +111,28 @@ define i32* @test6_2() #0 { ; Function Attrs: nounwind readnone ssp uwtable define internal i8* @f1(i8* readnone %0) local_unnamed_addr #0 { +; IS__TUNIT____-LABEL: define {{[^@]+}}@f1 +; IS__TUNIT____-SAME: (i8* noalias nofree nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr +; IS__TUNIT____-NEXT: [[TMP2:%.*]] = icmp eq i8* [[TMP0]], null +; IS__TUNIT____-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP5:%.*]] +; IS__TUNIT____: 3: +; IS__TUNIT____-NEXT: [[TMP4:%.*]] = tail call align 8 i8* @f2() +; IS__TUNIT____-NEXT: br label [[TMP5]] +; IS__TUNIT____: 5: +; IS__TUNIT____-NEXT: [[TMP6:%.*]] = phi i8* [ [[TMP4]], [[TMP3]] ], [ [[TMP0]], [[TMP1:%.*]] ] +; IS__TUNIT____-NEXT: ret i8* [[TMP6]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@f1 +; IS__CGSCC____-SAME: (i8* nofree nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr +; IS__CGSCC____-NEXT: [[TMP2:%.*]] = icmp eq i8* [[TMP0]], null +; IS__CGSCC____-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP5:%.*]] +; IS__CGSCC____: 3: +; IS__CGSCC____-NEXT: [[TMP4:%.*]] = tail call align 8 i8* @f2() +; IS__CGSCC____-NEXT: br label [[TMP5]] +; IS__CGSCC____: 5: +; IS__CGSCC____-NEXT: [[TMP6:%.*]] = phi i8* [ [[TMP4]], [[TMP3]] ], [ [[TMP0]], [[TMP1:%.*]] ] +; IS__CGSCC____-NEXT: ret i8* [[TMP6]] +; %2 = icmp eq i8* %0, null br i1 %2, label %3, label %5 @@ -102,6 +148,19 @@ define internal i8* @f1(i8* readnone %0) local_unnamed_addr #0 { ; Function Attrs: nounwind readnone ssp uwtable define internal i8* @f2(i8* readnone %0) local_unnamed_addr #0 { +; CHECK-LABEL: define {{[^@]+}}@f2() local_unnamed_addr +; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8* @a1, null +; CHECK-NEXT: br i1 [[TMP1]], label [[TMP4:%.*]], label [[TMP2:%.*]] +; CHECK: 2: +; CHECK-NEXT: [[TMP3:%.*]] = tail call i8* @f1(i8* noalias nofree nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" @a1) +; CHECK-NEXT: br label [[TMP6:%.*]] +; CHECK: 4: +; CHECK-NEXT: [[TMP5:%.*]] = tail call i8* @f3() +; CHECK-NEXT: br label [[TMP6]] +; CHECK: 6: +; CHECK-NEXT: [[TMP7:%.*]] = phi i8* [ [[TMP3]], [[TMP2]] ], [ [[TMP5]], [[TMP4]] ] +; CHECK-NEXT: ret i8* [[TMP7]] +; %2 = icmp eq i8* %0, null br i1 %2, label %5, label %3 @@ -121,6 +180,16 @@ define internal i8* @f2(i8* readnone %0) local_unnamed_addr #0 { ; Function Attrs: nounwind readnone ssp uwtable define internal i8* @f3(i8* readnone %0) local_unnamed_addr #0 { +; CHECK-LABEL: define {{[^@]+}}@f3() local_unnamed_addr +; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8* @a2, null +; CHECK-NEXT: br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP4:%.*]] +; CHECK: 2: +; CHECK-NEXT: [[TMP3:%.*]] = tail call i8* @f1(i8* noalias nofree nonnull readnone align 16 dereferenceable(1) @a2) +; CHECK-NEXT: br label [[TMP4]] +; CHECK: 4: +; CHECK-NEXT: [[TMP5:%.*]] = phi i8* [ [[TMP3]], [[TMP2]] ], [ @a1, [[TMP0:%.*]] ] +; CHECK-NEXT: ret i8* [[TMP5]] +; %2 = icmp eq i8* %0, null br i1 %2, label %3, label %5 @@ -133,18 +202,16 @@ define internal i8* @f3(i8* readnone %0) local_unnamed_addr #0 { ret i8* %6 } -; UTC_ARGS: --enable - ; TEST 7 ; Better than IR information define align 4 i8* @test7() #0 { -; ATTRIBUTOR_MODULE-LABEL: define {{[^@]+}}@test7() -; ATTRIBUTOR_MODULE-NEXT: [[C:%.*]] = tail call i8* @f1(i8* noalias nofree nonnull readnone align 8 dereferenceable(1) @a1) -; ATTRIBUTOR_MODULE-NEXT: ret i8* [[C]] +; IS__TUNIT____-LABEL: define {{[^@]+}}@test7() +; IS__TUNIT____-NEXT: [[C:%.*]] = tail call i8* @f1(i8* noalias nofree nonnull readnone align 8 dereferenceable(1) @a1) +; IS__TUNIT____-NEXT: ret i8* [[C]] ; -; ATTRIBUTOR_CGSCC-LABEL: define {{[^@]+}}@test7() -; ATTRIBUTOR_CGSCC-NEXT: [[C:%.*]] = tail call nonnull align 8 dereferenceable(1) i8* @f1(i8* noalias nofree nonnull readnone align 8 dereferenceable(1) @a1) -; ATTRIBUTOR_CGSCC-NEXT: ret i8* [[C]] +; IS__CGSCC____-LABEL: define {{[^@]+}}@test7() +; IS__CGSCC____-NEXT: [[C:%.*]] = tail call nonnull align 8 dereferenceable(1) i8* @f1(i8* noalias nofree nonnull readnone align 8 dereferenceable(1) @a1) +; IS__CGSCC____-NEXT: ret i8* [[C]] ; %c = tail call i8* @f1(i8* align 8 dereferenceable(1) @a1) ret i8* %c @@ -153,31 +220,31 @@ define align 4 i8* @test7() #0 { ; TEST 7b ; Function Attrs: nounwind readnone ssp uwtable define internal i8* @f1b(i8* readnone %0) local_unnamed_addr #0 { -; ATTRIBUTOR_MODULE-LABEL: define {{[^@]+}}@f1b -; ATTRIBUTOR_MODULE-SAME: (i8* noalias nofree nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr -; ATTRIBUTOR_MODULE-NEXT: [[TMP2:%.*]] = icmp eq i8* [[TMP0]], null -; ATTRIBUTOR_MODULE-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP5:%.*]] -; ATTRIBUTOR_MODULE: 3: -; ATTRIBUTOR_MODULE-NEXT: [[TMP4:%.*]] = tail call align 8 i8* @f2b() -; ATTRIBUTOR_MODULE-NEXT: [[L:%.*]] = load i8, i8* [[TMP4]], align 8 -; ATTRIBUTOR_MODULE-NEXT: store i8 [[L]], i8* @a1, align 8 -; ATTRIBUTOR_MODULE-NEXT: br label [[TMP5]] -; ATTRIBUTOR_MODULE: 5: -; ATTRIBUTOR_MODULE-NEXT: [[TMP6:%.*]] = phi i8* [ [[TMP4]], [[TMP3]] ], [ [[TMP0]], [[TMP1:%.*]] ] -; ATTRIBUTOR_MODULE-NEXT: ret i8* [[TMP6]] +; IS__TUNIT____-LABEL: define {{[^@]+}}@f1b +; IS__TUNIT____-SAME: (i8* noalias nofree nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr +; IS__TUNIT____-NEXT: [[TMP2:%.*]] = icmp eq i8* [[TMP0]], null +; IS__TUNIT____-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP5:%.*]] +; IS__TUNIT____: 3: +; IS__TUNIT____-NEXT: [[TMP4:%.*]] = tail call align 8 i8* @f2b() +; IS__TUNIT____-NEXT: [[L:%.*]] = load i8, i8* [[TMP4]], align 8 +; IS__TUNIT____-NEXT: store i8 [[L]], i8* @a1, align 8 +; IS__TUNIT____-NEXT: br label [[TMP5]] +; IS__TUNIT____: 5: +; IS__TUNIT____-NEXT: [[TMP6:%.*]] = phi i8* [ [[TMP4]], [[TMP3]] ], [ [[TMP0]], [[TMP1:%.*]] ] +; IS__TUNIT____-NEXT: ret i8* [[TMP6]] ; -; ATTRIBUTOR_CGSCC-LABEL: define {{[^@]+}}@f1b -; ATTRIBUTOR_CGSCC-SAME: (i8* nofree nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr -; ATTRIBUTOR_CGSCC-NEXT: [[TMP2:%.*]] = icmp eq i8* [[TMP0]], null -; ATTRIBUTOR_CGSCC-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP5:%.*]] -; ATTRIBUTOR_CGSCC: 3: -; ATTRIBUTOR_CGSCC-NEXT: [[TMP4:%.*]] = tail call align 8 i8* @f2b() -; ATTRIBUTOR_CGSCC-NEXT: [[L:%.*]] = load i8, i8* [[TMP4]], align 8 -; ATTRIBUTOR_CGSCC-NEXT: store i8 [[L]], i8* @a1, align 8 -; ATTRIBUTOR_CGSCC-NEXT: br label [[TMP5]] -; ATTRIBUTOR_CGSCC: 5: -; ATTRIBUTOR_CGSCC-NEXT: [[TMP6:%.*]] = phi i8* [ [[TMP4]], [[TMP3]] ], [ [[TMP0]], [[TMP1:%.*]] ] -; ATTRIBUTOR_CGSCC-NEXT: ret i8* [[TMP6]] +; IS__CGSCC____-LABEL: define {{[^@]+}}@f1b +; IS__CGSCC____-SAME: (i8* nofree nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr +; IS__CGSCC____-NEXT: [[TMP2:%.*]] = icmp eq i8* [[TMP0]], null +; IS__CGSCC____-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP5:%.*]] +; IS__CGSCC____: 3: +; IS__CGSCC____-NEXT: [[TMP4:%.*]] = tail call align 8 i8* @f2b() +; IS__CGSCC____-NEXT: [[L:%.*]] = load i8, i8* [[TMP4]], align 8 +; IS__CGSCC____-NEXT: store i8 [[L]], i8* @a1, align 8 +; IS__CGSCC____-NEXT: br label [[TMP5]] +; IS__CGSCC____: 5: +; IS__CGSCC____-NEXT: [[TMP6:%.*]] = phi i8* [ [[TMP4]], [[TMP3]] ], [ [[TMP0]], [[TMP1:%.*]] ] +; IS__CGSCC____-NEXT: ret i8* [[TMP6]] ; %2 = icmp eq i8* %0, null br i1 %2, label %3, label %5 @@ -196,18 +263,18 @@ define internal i8* @f1b(i8* readnone %0) local_unnamed_addr #0 { ; Function Attrs: nounwind readnone ssp uwtable define internal i8* @f2b(i8* readnone %0) local_unnamed_addr #0 { ; -; ATTRIBUTOR-LABEL: define {{[^@]+}}@f2b() local_unnamed_addr -; ATTRIBUTOR-NEXT: [[TMP1:%.*]] = icmp eq i8* @a1, null -; ATTRIBUTOR-NEXT: br i1 [[TMP1]], label [[TMP4:%.*]], label [[TMP2:%.*]] -; ATTRIBUTOR: 2: -; ATTRIBUTOR-NEXT: [[TMP3:%.*]] = tail call i8* @f1b(i8* noalias nofree nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" @a1) -; ATTRIBUTOR-NEXT: br label [[TMP6:%.*]] -; ATTRIBUTOR: 4: -; ATTRIBUTOR-NEXT: [[TMP5:%.*]] = tail call i8* @f3b() -; ATTRIBUTOR-NEXT: br label [[TMP6]] -; ATTRIBUTOR: 6: -; ATTRIBUTOR-NEXT: [[TMP7:%.*]] = phi i8* [ [[TMP3]], [[TMP2]] ], [ [[TMP5]], [[TMP4]] ] -; ATTRIBUTOR-NEXT: ret i8* [[TMP7]] +; CHECK-LABEL: define {{[^@]+}}@f2b() local_unnamed_addr +; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8* @a1, null +; CHECK-NEXT: br i1 [[TMP1]], label [[TMP4:%.*]], label [[TMP2:%.*]] +; CHECK: 2: +; CHECK-NEXT: [[TMP3:%.*]] = tail call i8* @f1b(i8* noalias nofree nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" @a1) +; CHECK-NEXT: br label [[TMP6:%.*]] +; CHECK: 4: +; CHECK-NEXT: [[TMP5:%.*]] = tail call i8* @f3b() +; CHECK-NEXT: br label [[TMP6]] +; CHECK: 6: +; CHECK-NEXT: [[TMP7:%.*]] = phi i8* [ [[TMP3]], [[TMP2]] ], [ [[TMP5]], [[TMP4]] ] +; CHECK-NEXT: ret i8* [[TMP7]] ; %2 = icmp eq i8* %0, null br i1 %2, label %5, label %3 @@ -229,15 +296,15 @@ define internal i8* @f2b(i8* readnone %0) local_unnamed_addr #0 { ; Function Attrs: nounwind readnone ssp uwtable define internal i8* @f3b(i8* readnone %0) local_unnamed_addr #0 { ; -; ATTRIBUTOR-LABEL: define {{[^@]+}}@f3b() local_unnamed_addr -; ATTRIBUTOR-NEXT: [[TMP1:%.*]] = icmp eq i8* @a2, null -; ATTRIBUTOR-NEXT: br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP4:%.*]] -; ATTRIBUTOR: 2: -; ATTRIBUTOR-NEXT: [[TMP3:%.*]] = tail call i8* @f1b(i8* noalias nofree nonnull readnone align 16 dereferenceable(1) @a2) -; ATTRIBUTOR-NEXT: br label [[TMP4]] -; ATTRIBUTOR: 4: -; ATTRIBUTOR-NEXT: [[TMP5:%.*]] = phi i8* [ [[TMP3]], [[TMP2]] ], [ @a1, [[TMP0:%.*]] ] -; ATTRIBUTOR-NEXT: ret i8* [[TMP5]] +; CHECK-LABEL: define {{[^@]+}}@f3b() local_unnamed_addr +; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8* @a2, null +; CHECK-NEXT: br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP4:%.*]] +; CHECK: 2: +; CHECK-NEXT: [[TMP3:%.*]] = tail call i8* @f1b(i8* noalias nofree nonnull readnone align 16 dereferenceable(1) @a2) +; CHECK-NEXT: br label [[TMP4]] +; CHECK: 4: +; CHECK-NEXT: [[TMP5:%.*]] = phi i8* [ [[TMP3]], [[TMP2]] ], [ @a1, [[TMP0:%.*]] ] +; CHECK-NEXT: ret i8* [[TMP5]] ; %2 = icmp eq i8* %0, null br i1 %2, label %3, label %5 @@ -252,36 +319,52 @@ define internal i8* @f3b(i8* readnone %0) local_unnamed_addr #0 { } define align 4 i32* @test7b(i32* align 32 %p) #0 { -; ATTRIBUTOR-LABEL: define {{[^@]+}}@test7b -; ATTRIBUTOR-SAME: (i32* nofree readnone returned align 32 "no-capture-maybe-returned" [[P:%.*]]) -; ATTRIBUTOR-NEXT: [[TMP1:%.*]] = tail call i8* @f1b(i8* noalias nofree nonnull readnone align 8 dereferenceable(1) @a1) -; ATTRIBUTOR-NEXT: ret i32* [[P]] +; CHECK-LABEL: define {{[^@]+}}@test7b +; CHECK-SAME: (i32* nofree readnone returned align 32 "no-capture-maybe-returned" [[P:%.*]]) +; CHECK-NEXT: [[TMP1:%.*]] = tail call i8* @f1b(i8* noalias nofree nonnull readnone align 8 dereferenceable(1) @a1) +; CHECK-NEXT: ret i32* [[P]] ; tail call i8* @f1b(i8* align 8 dereferenceable(1) @a1) ret i32* %p } -; UTC_ARGS: --disable - ; TEST 8 define void @test8_helper() { +; CHECK-LABEL: define {{[^@]+}}@test8_helper() +; CHECK-NEXT: [[PTR0:%.*]] = tail call i32* @unknown() +; CHECK-NEXT: [[PTR1:%.*]] = tail call align 4 i32* @unknown() +; CHECK-NEXT: [[PTR2:%.*]] = tail call align 8 i32* @unknown() +; CHECK-NEXT: tail call void @test8(i32* noalias readnone align 4 [[PTR1]], i32* noalias readnone align 4 [[PTR1]], i32* noalias readnone [[PTR0]]) +; CHECK-NEXT: tail call void @test8(i32* noalias readnone align 8 [[PTR2]], i32* noalias readnone align 4 [[PTR1]], i32* noalias readnone align 4 [[PTR1]]) +; CHECK-NEXT: tail call void @test8(i32* noalias readnone align 8 [[PTR2]], i32* noalias readnone align 4 [[PTR1]], i32* noalias readnone align 4 [[PTR1]]) +; CHECK-NEXT: ret void +; %ptr0 = tail call i32* @unknown() %ptr1 = tail call align 4 i32* @unknown() %ptr2 = tail call align 8 i32* @unknown() tail call void @test8(i32* %ptr1, i32* %ptr1, i32* %ptr0) -; ATTRIBUTOR: tail call void @test8(i32* noalias readnone align 4 %ptr1, i32* noalias readnone align 4 %ptr1, i32* noalias readnone %ptr0) tail call void @test8(i32* %ptr2, i32* %ptr1, i32* %ptr1) -; ATTRIBUTOR: tail call void @test8(i32* noalias readnone align 8 %ptr2, i32* noalias readnone align 4 %ptr1, i32* noalias readnone align 4 %ptr1) tail call void @test8(i32* %ptr2, i32* %ptr1, i32* %ptr1) -; ATTRIBUTOR: tail call void @test8(i32* noalias readnone align 8 %ptr2, i32* noalias readnone align 4 %ptr1, i32* noalias readnone align 4 %ptr1) ret void } declare void @user_i32_ptr(i32* nocapture readnone) nounwind define internal void @test8(i32* %a, i32* %b, i32* %c) { -; ATTRIBUTOR_MODULE: define internal void @test8(i32* noalias nocapture readnone align 4 %a, i32* noalias nocapture readnone align 4 %b, i32* noalias nocapture readnone %c) -; ATTRIBUTOR_CGSCC: define internal void @test8(i32* nocapture readnone align 4 %a, i32* nocapture readnone align 4 %b, i32* nocapture readnone %c) +; IS__TUNIT____-LABEL: define {{[^@]+}}@test8 +; IS__TUNIT____-SAME: (i32* noalias nocapture readnone align 4 [[A:%.*]], i32* noalias nocapture readnone align 4 [[B:%.*]], i32* noalias nocapture readnone [[C:%.*]]) +; IS__TUNIT____-NEXT: call void @user_i32_ptr(i32* noalias nocapture readnone align 4 [[A]]) +; IS__TUNIT____-NEXT: call void @user_i32_ptr(i32* noalias nocapture readnone align 4 [[B]]) +; IS__TUNIT____-NEXT: call void @user_i32_ptr(i32* noalias nocapture readnone [[C]]) +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@test8 +; IS__CGSCC____-SAME: (i32* nocapture readnone align 4 [[A:%.*]], i32* nocapture readnone align 4 [[B:%.*]], i32* nocapture readnone [[C:%.*]]) +; IS__CGSCC____-NEXT: call void @user_i32_ptr(i32* noalias nocapture readnone align 4 [[A]]) +; IS__CGSCC____-NEXT: call void @user_i32_ptr(i32* noalias nocapture readnone align 4 [[B]]) +; IS__CGSCC____-NEXT: call void @user_i32_ptr(i32* noalias nocapture readnone [[C]]) +; IS__CGSCC____-NEXT: ret void +; call void @user_i32_ptr(i32* %a) call void @user_i32_ptr(i32* %b) call void @user_i32_ptr(i32* %c) @@ -289,33 +372,53 @@ define internal void @test8(i32* %a, i32* %b, i32* %c) { } declare void @test9_helper(i32* %A) -define void @test9_traversal(i1 %c, i32* align 4 %B, i32* align 8 %C) { - %sel = select i1 %c, i32* %B, i32* %C +define void @test9_traversal(i1 %cnd, i32* align 4 %B, i32* align 8 %C) { +; CHECK-LABEL: define {{[^@]+}}@test9_traversal +; CHECK-SAME: (i1 [[CND:%.*]], i32* align 4 [[B:%.*]], i32* align 8 [[C:%.*]]) +; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CND]], i32* [[B]], i32* [[C]] +; CHECK-NEXT: call void @test9_helper(i32* align 4 [[SEL]]) +; CHECK-NEXT: ret void +; + %sel = select i1 %cnd, i32* %B, i32* %C call void @test9_helper(i32* %sel) ret void } ; FIXME: This will work with an upcoming patch (D66618 or similar) ; define align 32 i32* @test10a(i32* align 32 "no-capture-maybe-returned" %p) -; ATTRIBUTOR: define i32* @test10a(i32* nofree nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" %p) +; FIXME: This will work with an upcoming patch (D66618 or similar) +; store i32 1, i32* %r, align 32 +; FIXME: This will work with an upcoming patch (D66618 or similar) +; store i32 -1, i32* %g1, align 32 define i32* @test10a(i32* align 32 %p) { -; ATTRIBUTOR: %l = load i32, i32* %p, align 32 +; CHECK-LABEL: define {{[^@]+}}@test10a +; CHECK-SAME: (i32* nofree nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]]) +; CHECK-NEXT: [[L:%.*]] = load i32, i32* [[P]], align 32 +; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[L]], 0 +; CHECK-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] +; CHECK: t: +; CHECK-NEXT: [[R:%.*]] = call i32* @test10a(i32* nofree nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P]]) +; CHECK-NEXT: store i32 1, i32* [[R]] +; CHECK-NEXT: [[G0:%.*]] = getelementptr i32, i32* [[P]], i32 8 +; CHECK-NEXT: br label [[E:%.*]] +; CHECK: f: +; CHECK-NEXT: [[G1:%.*]] = getelementptr i32, i32* [[P]], i32 8 +; CHECK-NEXT: store i32 -1, i32* [[G1]], align 4 +; CHECK-NEXT: br label [[E]] +; CHECK: e: +; CHECK-NEXT: [[PHI:%.*]] = phi i32* [ [[G0]], [[T]] ], [ [[G1]], [[F]] ] +; CHECK-NEXT: ret i32* [[PHI]] +; %l = load i32, i32* %p %c = icmp eq i32 %l, 0 br i1 %c, label %t, label %f t: %r = call i32* @test10a(i32* %p) -; FIXME: This will work with an upcoming patch (D66618 or similar) -; store i32 1, i32* %r, align 32 -; ATTRIBUTOR: store i32 1, i32* %r store i32 1, i32* %r %g0 = getelementptr i32, i32* %p, i32 8 br label %e f: %g1 = getelementptr i32, i32* %p, i32 8 -; FIXME: This will work with an upcoming patch (D66618 or similar) -; store i32 -1, i32* %g1, align 32 -; ATTRIBUTOR: store i32 -1, i32* %g1 store i32 -1, i32* %g1 br label %e e: @@ -325,25 +428,39 @@ e: ; FIXME: This will work with an upcoming patch (D66618 or similar) ; define align 32 i32* @test10b(i32* align 32 "no-capture-maybe-returned" %p) -; ATTRIBUTOR: define i32* @test10b(i32* nofree nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" %p) +; FIXME: This will work with an upcoming patch (D66618 or similar) +; store i32 1, i32* %r, align 32 +; FIXME: This will work with an upcoming patch (D66618 or similar) +; store i32 -1, i32* %g1, align 32 define i32* @test10b(i32* align 32 %p) { -; ATTRIBUTOR: %l = load i32, i32* %p, align 32 +; CHECK-LABEL: define {{[^@]+}}@test10b +; CHECK-SAME: (i32* nofree nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]]) +; CHECK-NEXT: [[L:%.*]] = load i32, i32* [[P]], align 32 +; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[L]], 0 +; CHECK-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] +; CHECK: t: +; CHECK-NEXT: [[R:%.*]] = call i32* @test10b(i32* nofree nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P]]) +; CHECK-NEXT: store i32 1, i32* [[R]] +; CHECK-NEXT: [[G0:%.*]] = getelementptr i32, i32* [[P]], i32 8 +; CHECK-NEXT: br label [[E:%.*]] +; CHECK: f: +; CHECK-NEXT: [[G1:%.*]] = getelementptr i32, i32* [[P]], i32 -8 +; CHECK-NEXT: store i32 -1, i32* [[G1]], align 4 +; CHECK-NEXT: br label [[E]] +; CHECK: e: +; CHECK-NEXT: [[PHI:%.*]] = phi i32* [ [[G0]], [[T]] ], [ [[G1]], [[F]] ] +; CHECK-NEXT: ret i32* [[PHI]] +; %l = load i32, i32* %p %c = icmp eq i32 %l, 0 br i1 %c, label %t, label %f t: %r = call i32* @test10b(i32* %p) -; FIXME: This will work with an upcoming patch (D66618 or similar) -; store i32 1, i32* %r, align 32 -; ATTRIBUTOR: store i32 1, i32* %r store i32 1, i32* %r %g0 = getelementptr i32, i32* %p, i32 8 br label %e f: %g1 = getelementptr i32, i32* %p, i32 -8 -; FIXME: This will work with an upcoming patch (D66618 or similar) -; store i32 -1, i32* %g1, align 32 -; ATTRIBUTOR: store i32 -1, i32* %g1 store i32 -1, i32* %g1 br label %e e: @@ -352,8 +469,13 @@ e: } -; ATTRIBUTOR: define i64 @test11(i32* nocapture nofree nonnull readonly align 8 dereferenceable(8) %p) define i64 @test11(i32* %p) { +; CHECK-LABEL: define {{[^@]+}}@test11 +; CHECK-SAME: (i32* nocapture nofree nonnull readonly align 8 dereferenceable(8) [[P:%.*]]) +; CHECK-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* +; CHECK-NEXT: [[RET:%.*]] = load i64, i64* [[P_CAST]], align 8 +; CHECK-NEXT: ret i64 [[RET]] +; %p-cast = bitcast i32* %p to i64* %ret = load i64, i64* %p-cast, align 8 ret i64 %ret @@ -363,8 +485,15 @@ define i64 @test11(i32* %p) { ; Test for deduction using must-be-executed-context and GEP instruction ; FXIME: %p should have nonnull -; ATTRIBUTOR: define i64 @test12-1(i32* nocapture nofree readonly align 16 %p) define i64 @test12-1(i32* align 4 %p) { +; CHECK-LABEL: define {{[^@]+}}@test12-1 +; CHECK-SAME: (i32* nocapture nofree readonly align 16 [[P:%.*]]) +; CHECK-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* +; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 1 +; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr i64, i64* [[ARRAYIDX0]], i64 3 +; CHECK-NEXT: [[RET:%.*]] = load i64, i64* [[ARRAYIDX1]], align 16 +; CHECK-NEXT: ret i64 [[RET]] +; %p-cast = bitcast i32* %p to i64* %arrayidx0 = getelementptr i64, i64* %p-cast, i64 1 %arrayidx1 = getelementptr i64, i64* %arrayidx0, i64 3 @@ -372,8 +501,14 @@ define i64 @test12-1(i32* align 4 %p) { ret i64 %ret } -; ATTRIBUTOR: define i64 @test12-2(i32* nocapture nofree nonnull readonly align 16 dereferenceable(8) %p) define i64 @test12-2(i32* align 4 %p) { +; CHECK-LABEL: define {{[^@]+}}@test12-2 +; CHECK-SAME: (i32* nocapture nofree nonnull readonly align 16 dereferenceable(8) [[P:%.*]]) +; CHECK-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* +; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 0 +; CHECK-NEXT: [[RET:%.*]] = load i64, i64* [[ARRAYIDX0]], align 16 +; CHECK-NEXT: ret i64 [[RET]] +; %p-cast = bitcast i32* %p to i64* %arrayidx0 = getelementptr i64, i64* %p-cast, i64 0 %ret = load i64, i64* %arrayidx0, align 16 @@ -381,8 +516,15 @@ define i64 @test12-2(i32* align 4 %p) { } ; FXIME: %p should have nonnull -; ATTRIBUTOR: define void @test12-3(i32* nocapture nofree writeonly align 16 %p) define void @test12-3(i32* align 4 %p) { +; CHECK-LABEL: define {{[^@]+}}@test12-3 +; CHECK-SAME: (i32* nocapture nofree writeonly align 16 [[P:%.*]]) +; CHECK-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* +; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 1 +; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr i64, i64* [[ARRAYIDX0]], i64 3 +; CHECK-NEXT: store i64 0, i64* [[ARRAYIDX1]], align 16 +; CHECK-NEXT: ret void +; %p-cast = bitcast i32* %p to i64* %arrayidx0 = getelementptr i64, i64* %p-cast, i64 1 %arrayidx1 = getelementptr i64, i64* %arrayidx0, i64 3 @@ -390,8 +532,14 @@ define void @test12-3(i32* align 4 %p) { ret void } -; ATTRIBUTOR: define void @test12-4(i32* nocapture nofree nonnull writeonly align 16 dereferenceable(8) %p) define void @test12-4(i32* align 4 %p) { +; CHECK-LABEL: define {{[^@]+}}@test12-4 +; CHECK-SAME: (i32* nocapture nofree nonnull writeonly align 16 dereferenceable(8) [[P:%.*]]) +; CHECK-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* +; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 0 +; CHECK-NEXT: store i64 0, i64* [[ARRAYIDX0]], align 16 +; CHECK-NEXT: ret void +; %p-cast = bitcast i32* %p to i64* %arrayidx0 = getelementptr i64, i64* %p-cast, i64 0 store i64 0, i64* %arrayidx0, align 16 @@ -400,8 +548,15 @@ define void @test12-4(i32* align 4 %p) { declare void @use(i64*) willreturn nounwind -; ATTRIBUTOR: define void @test12-5(i32* align 16 %p) define void @test12-5(i32* align 4 %p) { +; CHECK-LABEL: define {{[^@]+}}@test12-5 +; CHECK-SAME: (i32* align 16 [[P:%.*]]) +; CHECK-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* +; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 1 +; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr i64, i64* [[ARRAYIDX0]], i64 3 +; CHECK-NEXT: tail call void @use(i64* align 16 [[ARRAYIDX1]]) +; CHECK-NEXT: ret void +; %p-cast = bitcast i32* %p to i64* %arrayidx0 = getelementptr i64, i64* %p-cast, i64 1 %arrayidx1 = getelementptr i64, i64* %arrayidx0, i64 3 @@ -409,8 +564,14 @@ define void @test12-5(i32* align 4 %p) { ret void } -; ATTRIBUTOR: define void @test12-6(i32* align 16 %p) define void @test12-6(i32* align 4 %p) { +; CHECK-LABEL: define {{[^@]+}}@test12-6 +; CHECK-SAME: (i32* align 16 [[P:%.*]]) +; CHECK-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* +; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 0 +; CHECK-NEXT: tail call void @use(i64* align 16 [[ARRAYIDX0]]) +; CHECK-NEXT: ret void +; %p-cast = bitcast i32* %p to i64* %arrayidx0 = getelementptr i64, i64* %p-cast, i64 0 tail call void @use(i64* align 16 %arrayidx0) @@ -418,17 +579,17 @@ define void @test12-6(i32* align 4 %p) { } define void @test13(i1 %c, i32* align 32 %dst) #0 { -; ATTRIBUTOR-LABEL: define {{[^@]+}}@test13 -; ATTRIBUTOR-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) -; ATTRIBUTOR-NEXT: br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]] -; ATTRIBUTOR: truebb: -; ATTRIBUTOR-NEXT: br label [[END:%.*]] -; ATTRIBUTOR: falsebb: -; ATTRIBUTOR-NEXT: br label [[END]] -; ATTRIBUTOR: end: -; ATTRIBUTOR-NEXT: [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ null, [[FALSEBB]] ] -; ATTRIBUTOR-NEXT: store i32 0, i32* [[PTR]], align 32 -; ATTRIBUTOR-NEXT: ret void +; CHECK-LABEL: define {{[^@]+}}@test13 +; CHECK-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) +; CHECK-NEXT: br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]] +; CHECK: truebb: +; CHECK-NEXT: br label [[END:%.*]] +; CHECK: falsebb: +; CHECK-NEXT: br label [[END]] +; CHECK: end: +; CHECK-NEXT: [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ null, [[FALSEBB]] ] +; CHECK-NEXT: store i32 0, i32* [[PTR]], align 32 +; CHECK-NEXT: ret void ; br i1 %c, label %truebb, label %falsebb truebb: @@ -442,16 +603,17 @@ end: } define void @test13-1(i1 %c, i32* align 32 %dst) { -; ATTRIBUTOR-LABEL: @test13-1( -; ATTRIBUTOR-NEXT: br i1 [[C:%.*]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]] -; ATTRIBUTOR: truebb: -; ATTRIBUTOR-NEXT: br label [[END:%.*]] -; ATTRIBUTOR: falsebb: -; ATTRIBUTOR-NEXT: br label [[END]] -; ATTRIBUTOR: end: -; ATTRIBUTOR-NEXT: [[PTR:%.*]] = phi i32* [ [[DST:%.*]], [[TRUEBB]] ], [ inttoptr (i64 48 to i32*), [[FALSEBB]] ] -; ATTRIBUTOR-NEXT: store i32 0, i32* [[PTR]], align 16 -; ATTRIBUTOR-NEXT: ret void +; CHECK-LABEL: define {{[^@]+}}@test13-1 +; CHECK-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) +; CHECK-NEXT: br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]] +; CHECK: truebb: +; CHECK-NEXT: br label [[END:%.*]] +; CHECK: falsebb: +; CHECK-NEXT: br label [[END]] +; CHECK: end: +; CHECK-NEXT: [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ inttoptr (i64 48 to i32*), [[FALSEBB]] ] +; CHECK-NEXT: store i32 0, i32* [[PTR]], align 16 +; CHECK-NEXT: ret void ; br i1 %c, label %truebb, label %falsebb truebb: @@ -465,16 +627,17 @@ end: } define void @test13-2(i1 %c, i32* align 32 %dst) { -; ATTRIBUTOR-LABEL: @test13-2( -; ATTRIBUTOR-NEXT: br i1 [[C:%.*]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]] -; ATTRIBUTOR: truebb: -; ATTRIBUTOR-NEXT: br label [[END:%.*]] -; ATTRIBUTOR: falsebb: -; ATTRIBUTOR-NEXT: br label [[END]] -; ATTRIBUTOR: end: -; ATTRIBUTOR-NEXT: [[PTR:%.*]] = phi i32* [ [[DST:%.*]], [[TRUEBB]] ], [ inttoptr (i64 160 to i32*), [[FALSEBB]] ] -; ATTRIBUTOR-NEXT: store i32 0, i32* [[PTR]], align 32 -; ATTRIBUTOR-NEXT: ret void +; CHECK-LABEL: define {{[^@]+}}@test13-2 +; CHECK-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) +; CHECK-NEXT: br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]] +; CHECK: truebb: +; CHECK-NEXT: br label [[END:%.*]] +; CHECK: falsebb: +; CHECK-NEXT: br label [[END]] +; CHECK: end: +; CHECK-NEXT: [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ inttoptr (i64 160 to i32*), [[FALSEBB]] ] +; CHECK-NEXT: store i32 0, i32* [[PTR]], align 32 +; CHECK-NEXT: ret void ; br i1 %c, label %truebb, label %falsebb truebb: @@ -488,16 +651,17 @@ end: } define void @test13-3(i1 %c, i32* align 32 %dst) { -; ATTRIBUTOR-LABEL: @test13-3( -; ATTRIBUTOR-NEXT: br i1 [[C:%.*]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]] -; ATTRIBUTOR: truebb: -; ATTRIBUTOR-NEXT: br label [[END:%.*]] -; ATTRIBUTOR: falsebb: -; ATTRIBUTOR-NEXT: br label [[END]] -; ATTRIBUTOR: end: -; ATTRIBUTOR-NEXT: [[PTR:%.*]] = phi i32* [ [[DST:%.*]], [[TRUEBB]] ], [ inttoptr (i64 128 to i32*), [[FALSEBB]] ] -; ATTRIBUTOR-NEXT: store i32 0, i32* [[PTR]], align 32 -; ATTRIBUTOR-NEXT: ret void +; CHECK-LABEL: define {{[^@]+}}@test13-3 +; CHECK-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) +; CHECK-NEXT: br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]] +; CHECK: truebb: +; CHECK-NEXT: br label [[END:%.*]] +; CHECK: falsebb: +; CHECK-NEXT: br label [[END]] +; CHECK: end: +; CHECK-NEXT: [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ inttoptr (i64 128 to i32*), [[FALSEBB]] ] +; CHECK-NEXT: store i32 0, i32* [[PTR]], align 32 +; CHECK-NEXT: ret void ; br i1 %c, label %truebb, label %falsebb truebb: @@ -512,29 +676,42 @@ end: ; Don't crash on ptr2int/int2ptr uses. define i64 @ptr2int(i32* %p) { +; CHECK-LABEL: define {{[^@]+}}@ptr2int +; CHECK-SAME: (i32* nofree readnone [[P:%.*]]) +; CHECK-NEXT: [[P2I:%.*]] = ptrtoint i32* [[P]] to i64 +; CHECK-NEXT: ret i64 [[P2I]] +; %p2i = ptrtoint i32* %p to i64 ret i64 %p2i } define i64* @int2ptr(i64 %i) { +; CHECK-LABEL: define {{[^@]+}}@int2ptr +; CHECK-SAME: (i64 [[I:%.*]]) +; CHECK-NEXT: [[I2P:%.*]] = inttoptr i64 [[I]] to i64* +; CHECK-NEXT: ret i64* [[I2P]] +; %i2p = inttoptr i64 %i to i64* ret i64* %i2p } ; Use the store alignment only for the pointer operand. define void @aligned_store(i8* %Value, i8** %Ptr) { -; ATTRIBUTOR: define void @aligned_store(i8* nofree writeonly %Value, i8** nocapture nofree nonnull writeonly align 32 dereferenceable(8) %Ptr) +; CHECK-LABEL: define {{[^@]+}}@aligned_store +; CHECK-SAME: (i8* nofree writeonly [[VALUE:%.*]], i8** nocapture nofree nonnull writeonly align 32 dereferenceable(8) [[PTR:%.*]]) +; CHECK-NEXT: store i8* [[VALUE]], i8** [[PTR]], align 32 +; CHECK-NEXT: ret void +; store i8* %Value, i8** %Ptr, align 32 ret void } -; UTC_ARGS: --enable declare i8* @some_func(i8*) define void @align_call_op_not_store(i8* align 2048 %arg) { -; ATTRIBUTOR-LABEL: define {{[^@]+}}@align_call_op_not_store -; ATTRIBUTOR-SAME: (i8* align 2048 [[ARG:%.*]]) -; ATTRIBUTOR-NEXT: [[UNKNOWN:%.*]] = call i8* @some_func(i8* align 2048 [[ARG]]) -; ATTRIBUTOR-NEXT: store i8 0, i8* [[UNKNOWN]] -; ATTRIBUTOR-NEXT: ret void +; CHECK-LABEL: define {{[^@]+}}@align_call_op_not_store +; CHECK-SAME: (i8* align 2048 [[ARG:%.*]]) +; CHECK-NEXT: [[UNKNOWN:%.*]] = call i8* @some_func(i8* align 2048 [[ARG]]) +; CHECK-NEXT: store i8 0, i8* [[UNKNOWN]] +; CHECK-NEXT: ret void ; %unknown = call i8* @some_func(i8* %arg) store i8 0, i8* %unknown @@ -542,11 +719,11 @@ define void @align_call_op_not_store(i8* align 2048 %arg) { } define void @align_store_after_bc(i32* align 2048 %arg) { ; -; ATTRIBUTOR-LABEL: define {{[^@]+}}@align_store_after_bc -; ATTRIBUTOR-SAME: (i32* nocapture nofree nonnull writeonly align 2048 dereferenceable(1) [[ARG:%.*]]) -; ATTRIBUTOR-NEXT: [[BC:%.*]] = bitcast i32* [[ARG]] to i8* -; ATTRIBUTOR-NEXT: store i8 0, i8* [[BC]], align 2048 -; ATTRIBUTOR-NEXT: ret void +; CHECK-LABEL: define {{[^@]+}}@align_store_after_bc +; CHECK-SAME: (i32* nocapture nofree nonnull writeonly align 2048 dereferenceable(1) [[ARG:%.*]]) +; CHECK-NEXT: [[BC:%.*]] = bitcast i32* [[ARG]] to i8* +; CHECK-NEXT: store i8 0, i8* [[BC]], align 2048 +; CHECK-NEXT: ret void ; %bc = bitcast i32* %arg to i8* store i8 0, i8* %bc @@ -557,10 +734,35 @@ define void @align_store_after_bc(i32* align 2048 %arg) { ; we cannot also put on the caller. @cnd = external global i1 define i32 @musttail_callee_1(i32* %p) { +; CHECK-LABEL: define {{[^@]+}}@musttail_callee_1 +; CHECK-SAME: (i32* nocapture nofree nonnull readonly dereferenceable(4) [[P:%.*]]) +; CHECK-NEXT: [[V:%.*]] = load i32, i32* [[P]], align 32 +; CHECK-NEXT: ret i32 [[V]] +; %v = load i32, i32* %p, align 32 ret i32 %v } define i32 @musttail_caller_1(i32* %p) { +; IS__TUNIT____-LABEL: define {{[^@]+}}@musttail_caller_1 +; IS__TUNIT____-SAME: (i32* nocapture nofree readonly [[P:%.*]]) +; IS__TUNIT____-NEXT: [[C:%.*]] = load i1, i1* @cnd, align 1 +; IS__TUNIT____-NEXT: br i1 [[C]], label [[MT:%.*]], label [[EXIT:%.*]] +; IS__TUNIT____: mt: +; IS__TUNIT____-NEXT: [[V:%.*]] = musttail call i32 @musttail_callee_1(i32* nocapture nofree readonly [[P]]) +; IS__TUNIT____-NEXT: ret i32 [[V]] +; IS__TUNIT____: exit: +; IS__TUNIT____-NEXT: ret i32 0 +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@musttail_caller_1 +; IS__CGSCC____-SAME: (i32* nocapture nofree readonly [[P:%.*]]) +; IS__CGSCC____-NEXT: [[C:%.*]] = load i1, i1* @cnd, align 1 +; IS__CGSCC____-NEXT: br i1 [[C]], label [[MT:%.*]], label [[EXIT:%.*]] +; IS__CGSCC____: mt: +; IS__CGSCC____-NEXT: [[V:%.*]] = musttail call i32 @musttail_callee_1(i32* nocapture nofree nonnull readonly dereferenceable(4) [[P]]) +; IS__CGSCC____-NEXT: ret i32 [[V]] +; IS__CGSCC____: exit: +; IS__CGSCC____-NEXT: ret i32 0 +; %c = load i1, i1* @cnd br i1 %c, label %mt, label %exit mt: @@ -569,7 +771,6 @@ mt: exit: ret i32 0 } -; UTC_ARGS: --disable attributes #0 = { nounwind uwtable noinline } attributes #1 = { uwtable noinline } diff --git a/llvm/test/Transforms/Attributor/alwaysinline.ll b/llvm/test/Transforms/Attributor/alwaysinline.ll index 1be433310457..91a7e8fd21b5 100644 --- a/llvm/test/Transforms/Attributor/alwaysinline.ll +++ b/llvm/test/Transforms/Attributor/alwaysinline.ll @@ -1,14 +1,18 @@ -; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt -attributor -attributor-disable=false -attributor-annotate-decl-cs -attributor-max-iterations=5 -S < %s | FileCheck %s --check-prefix=CHECK +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 ; ; When a function is marked `alwaysinline` and is able to be inlined, ; we can IPO its boundaries ; the function is not exactly defined, and marked alwaysinline and can be inlined, ; so the function can be analyzed -; CHECK: Function Attrs: alwaysinline nofree nosync nounwind readnone willreturn +; CHECK: Function Attrs: alwaysinline +; CHECK-SAME: willreturn define linkonce void @inner1() alwaysinline { -; CHECK-LABEL: @inner1( +; CHECK-LABEL: define {{[^@]+}}@inner1() ; CHECK-NEXT: entry: ; CHECK-NEXT: ret void ; @@ -16,9 +20,10 @@ entry: ret void } -; CHECK: Function Attrs: nofree nosync nounwind readnone willreturn +; CHECK: Function Attrs: +; CHECK-SAME: willreturn define void @outer1() { -; CHECK-LABEL: @outer1( +; CHECK-LABEL: define {{[^@]+}}@outer1() ; CHECK-NEXT: entry: ; CHECK-NEXT: ret void ; @@ -31,7 +36,7 @@ entry: ; so it will not be analyzed ; CHECK-NOT: Function Attrs: define linkonce i32 @inner2() { -; CHECK-LABEL: @inner2( +; CHECK-LABEL: define {{[^@]+}}@inner2() ; CHECK-NEXT: entry: ; CHECK-NEXT: ret i32 1 ; @@ -41,9 +46,9 @@ entry: ; CHECK-NOT: Function Attrs define i32 @outer2() { -; CHECK-LABEL: @outer2( +; CHECK-LABEL: define {{[^@]+}}@outer2() ; CHECK-NEXT: entry: -; CHECK-NEXT: [[R:%.*]] = call i32 @inner2() #2 +; CHECK-NEXT: [[R:%.*]] = call i32 @inner2() ; CHECK-NEXT: ret i32 [[R]] ; entry: @@ -55,11 +60,15 @@ entry: ; it is `unexactly defined` and alwaysinline but cannot be inlined. ; so it will not be analyzed ; CHECK: Function Attrs: -; CHECK-NOT: nofree nosync nounwind readnone +; CHECK-NOT: nofree +; CHECK-NOT: nosync +; CHECK-NOT: nounwind +; CHECK-NOT: readnone define linkonce i32 @inner3(i8* %addr) alwaysinline { -; CHECK-LABEL: @inner3( +; CHECK-LABEL: define {{[^@]+}}@inner3 +; CHECK-SAME: (i8* [[ADDR:%.*]]) ; CHECK-NEXT: entry: -; CHECK-NEXT: indirectbr i8* [[ADDR:%.*]], [label [[ONE:%.*]], label %two] +; CHECK-NEXT: indirectbr i8* [[ADDR]], [label [[ONE:%.*]], label %two] ; CHECK: one: ; CHECK-NEXT: ret i32 42 ; CHECK: two: @@ -77,8 +86,9 @@ two: ; CHECK-NOT: Function Attrs: define i32 @outer3(i32 %x) { -; CHECK-LABEL: @outer3( -; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 42 +; CHECK-LABEL: define {{[^@]+}}@outer3 +; CHECK-SAME: (i32 [[X:%.*]]) +; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X]], 42 ; CHECK-NEXT: [[ADDR:%.*]] = select i1 [[CMP]], i8* blockaddress(@inner3, [[ONE:%.*]]), i8* blockaddress(@inner3, [[TWO:%.*]]) ; CHECK-NEXT: [[CALL:%.*]] = call i32 @inner3(i8* [[ADDR]]) ; CHECK-NEXT: ret i32 [[CALL]] diff --git a/llvm/test/Transforms/Attributor/callbacks.ll b/llvm/test/Transforms/Attributor/callbacks.ll index 12af0c8e1a7e..d6efa5326c68 100644 --- a/llvm/test/Transforms/Attributor/callbacks.ll +++ b/llvm/test/Transforms/Attributor/callbacks.ll @@ -1,8 +1,9 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes -; FIXME: Add -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations below. -; This flag was removed because max iterations is 2 in most cases, but in windows it is 1. -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa' -attributor-disable=false -attributor-annotate-decl-cs < %s | FileCheck %s -; ModuleID = 'callback_simple.c' +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 + target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" ; Test 0 @@ -15,19 +16,54 @@ target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16 ; transfer in both directions. define void @t0_caller(i32* %a) { -; CHECK-LABEL: define {{[^@]+}}@t0_caller -; CHECK-SAME: (i32* align 256 [[A:%.*]]) -; CHECK-NEXT: entry: -; CHECK-NEXT: [[B:%.*]] = alloca i32, align 32 -; CHECK-NEXT: [[C:%.*]] = alloca i32*, align 64 -; CHECK-NEXT: [[PTR:%.*]] = alloca i32, align 128 -; CHECK-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8* -; CHECK-NEXT: store i32 42, i32* [[B]], align 32 -; CHECK-NEXT: store i32* [[B]], i32** [[C]], align 64 -; CHECK-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t0_callback_broker(i32* noalias align 536870912 null, i32* nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nonnull bitcast (void (i32*, i32*, i32*, i64, i32**)* @t0_callback_callee to void (i32*, i32*, ...)*), i32* align 256 [[A]], i64 undef, i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C]]) -; CHECK-NEXT: ret void +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@t0_caller +; IS__TUNIT_OPM-SAME: (i32* align 256 [[A:%.*]]) +; IS__TUNIT_OPM-NEXT: entry: +; IS__TUNIT_OPM-NEXT: [[B:%.*]] = alloca i32, align 32 +; IS__TUNIT_OPM-NEXT: [[C:%.*]] = alloca i32*, align 64 +; IS__TUNIT_OPM-NEXT: [[PTR:%.*]] = alloca i32, align 128 +; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8* +; IS__TUNIT_OPM-NEXT: store i32 42, i32* [[B]], align 32 +; IS__TUNIT_OPM-NEXT: store i32* [[B]], i32** [[C]], align 64 +; IS__TUNIT_OPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t0_callback_broker(i32* noalias align 536870912 null, i32* nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nonnull bitcast (void (i32*, i32*, i32*, i64, i32**)* @t0_callback_callee to void (i32*, i32*, ...)*), i32* align 256 [[A]], i64 undef, i32** nocapture nonnull readonly align 64 dereferenceable(8) [[C]]) +; IS__TUNIT_OPM-NEXT: ret void +; +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@t0_caller +; IS__TUNIT_NPM-SAME: (i32* align 256 [[A:%.*]]) +; IS__TUNIT_NPM-NEXT: entry: +; IS__TUNIT_NPM-NEXT: [[B:%.*]] = alloca i32, align 32 +; IS__TUNIT_NPM-NEXT: [[C:%.*]] = alloca i32*, align 64 +; IS__TUNIT_NPM-NEXT: [[PTR:%.*]] = alloca i32, align 128 +; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8* +; IS__TUNIT_NPM-NEXT: store i32 42, i32* [[B]], align 32 +; IS__TUNIT_NPM-NEXT: store i32* [[B]], i32** [[C]], align 64 +; IS__TUNIT_NPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t0_callback_broker(i32* noalias align 536870912 null, i32* nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nonnull bitcast (void (i32*, i32*, i32*, i64, i32**)* @t0_callback_callee to void (i32*, i32*, ...)*), i32* align 256 [[A]], i64 undef, i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C]]) +; IS__TUNIT_NPM-NEXT: ret void +; +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@t0_caller +; IS__CGSCC_OPM-SAME: (i32* [[A:%.*]]) +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: [[B:%.*]] = alloca i32, align 32 +; IS__CGSCC_OPM-NEXT: [[C:%.*]] = alloca i32*, align 64 +; IS__CGSCC_OPM-NEXT: [[PTR:%.*]] = alloca i32, align 128 +; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8* +; IS__CGSCC_OPM-NEXT: store i32 42, i32* [[B]], align 32 +; IS__CGSCC_OPM-NEXT: store i32* [[B]], i32** [[C]], align 64 +; IS__CGSCC_OPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t0_callback_broker(i32* noalias align 536870912 null, i32* nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, i64, i32**)* @t0_callback_callee to void (i32*, i32*, ...)*), i32* [[A]], i64 99, i32** nonnull align 64 dereferenceable(8) [[C]]) +; IS__CGSCC_OPM-NEXT: ret void +; +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@t0_caller +; IS__CGSCC_NPM-SAME: (i32* align 256 [[A:%.*]]) +; IS__CGSCC_NPM-NEXT: entry: +; IS__CGSCC_NPM-NEXT: [[B:%.*]] = alloca i32, align 32 +; IS__CGSCC_NPM-NEXT: [[C:%.*]] = alloca i32*, align 64 +; IS__CGSCC_NPM-NEXT: [[PTR:%.*]] = alloca i32, align 128 +; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8* +; IS__CGSCC_NPM-NEXT: store i32 42, i32* [[B]], align 32 +; IS__CGSCC_NPM-NEXT: store i32* [[B]], i32** [[C]], align 64 +; IS__CGSCC_NPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t0_callback_broker(i32* noalias align 536870912 null, i32* nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, i64, i32**)* @t0_callback_callee to void (i32*, i32*, ...)*), i32* align 256 [[A]], i64 99, i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C]]) +; IS__CGSCC_NPM-NEXT: ret void ; - entry: %b = alloca i32, align 32 %c = alloca i32*, align 64 @@ -42,14 +78,33 @@ entry: ; Note that the first two arguments are provided by the callback_broker according to the callback in !1 below! ; The others are annotated with alignment information, amongst others, or even replaced by the constants passed to the call. define internal void @t0_callback_callee(i32* %is_not_null, i32* %ptr, i32* %a, i64 %b, i32** %c) { -; CHECK-LABEL: define {{[^@]+}}@t0_callback_callee -; CHECK-SAME: (i32* nocapture nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* align 256 [[A:%.*]], i64 [[B:%.*]], i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) -; CHECK-NEXT: entry: -; CHECK-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8 -; CHECK-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4 -; CHECK-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64 -; CHECK-NEXT: tail call void @t0_check(i32* align 256 [[A]], i64 99, i32* [[TMP0]]) -; CHECK-NEXT: ret void +; +; IS________OPM-LABEL: define {{[^@]+}}@t0_callback_callee +; IS________OPM-SAME: (i32* nocapture nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* align 256 [[A:%.*]], i64 [[B:%.*]], i32** nocapture nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) +; IS________OPM-NEXT: entry: +; IS________OPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8 +; IS________OPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4 +; IS________OPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64 +; IS________OPM-NEXT: tail call void @t0_check(i32* align 256 [[A]], i64 99, i32* [[TMP0]]) +; IS________OPM-NEXT: ret void +; +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@t0_callback_callee +; IS__TUNIT_NPM-SAME: (i32* nocapture nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* align 256 [[A:%.*]], i64 [[B:%.*]], i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) +; IS__TUNIT_NPM-NEXT: entry: +; IS__TUNIT_NPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8 +; IS__TUNIT_NPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4 +; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64 +; IS__TUNIT_NPM-NEXT: tail call void @t0_check(i32* align 256 [[A]], i64 99, i32* [[TMP0]]) +; IS__TUNIT_NPM-NEXT: ret void +; +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@t0_callback_callee +; IS__CGSCC_NPM-SAME: (i32* nocapture nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* align 256 [[A:%.*]], i64 [[B:%.*]], i32** nocapture nonnull readonly align 8 dereferenceable(8) [[C:%.*]]) +; IS__CGSCC_NPM-NEXT: entry: +; IS__CGSCC_NPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8 +; IS__CGSCC_NPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4 +; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 8 +; IS__CGSCC_NPM-NEXT: tail call void @t0_check(i32* align 256 [[A]], i64 99, i32* [[TMP0]]) +; IS__CGSCC_NPM-NEXT: ret void ; entry: %ptr_val = load i32, i32* %ptr, align 8 @@ -69,17 +124,53 @@ declare !callback !0 void @t0_callback_broker(i32*, i32*, void (i32*, i32*, ...) ; we deduce and propagate noalias and others properly. define void @t1_caller(i32* noalias %a) { -; CHECK-LABEL: define {{[^@]+}}@t1_caller -; CHECK-SAME: (i32* noalias nocapture align 256 [[A:%.*]]) -; CHECK-NEXT: entry: -; CHECK-NEXT: [[B:%.*]] = alloca i32, align 32 -; CHECK-NEXT: [[C:%.*]] = alloca i32*, align 64 -; CHECK-NEXT: [[PTR:%.*]] = alloca i32, align 128 -; CHECK-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8* -; CHECK-NEXT: store i32 42, i32* [[B]], align 32 -; CHECK-NEXT: store i32* [[B]], i32** [[C]], align 64 -; CHECK-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t1_callback_broker(i32* noalias align 536870912 null, i32* noalias nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nonnull bitcast (void (i32*, i32*, i32*, i64, i32**)* @t1_callback_callee to void (i32*, i32*, ...)*), i32* noalias nocapture align 256 [[A]], i64 undef, i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C]]) -; CHECK-NEXT: ret void +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@t1_caller +; IS__TUNIT_OPM-SAME: (i32* noalias nocapture align 256 [[A:%.*]]) +; IS__TUNIT_OPM-NEXT: entry: +; IS__TUNIT_OPM-NEXT: [[B:%.*]] = alloca i32, align 32 +; IS__TUNIT_OPM-NEXT: [[C:%.*]] = alloca i32*, align 64 +; IS__TUNIT_OPM-NEXT: [[PTR:%.*]] = alloca i32, align 128 +; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8* +; IS__TUNIT_OPM-NEXT: store i32 42, i32* [[B]], align 32 +; IS__TUNIT_OPM-NEXT: store i32* [[B]], i32** [[C]], align 64 +; IS__TUNIT_OPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t1_callback_broker(i32* noalias align 536870912 null, i32* nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nonnull bitcast (void (i32*, i32*, i32*, i64, i32**)* @t1_callback_callee to void (i32*, i32*, ...)*), i32* nocapture align 256 [[A]], i64 undef, i32** nocapture nonnull readonly align 64 dereferenceable(8) [[C]]) +; IS__TUNIT_OPM-NEXT: ret void +; +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@t1_caller +; IS__TUNIT_NPM-SAME: (i32* noalias nocapture align 256 [[A:%.*]]) +; IS__TUNIT_NPM-NEXT: entry: +; IS__TUNIT_NPM-NEXT: [[B:%.*]] = alloca i32, align 32 +; IS__TUNIT_NPM-NEXT: [[C:%.*]] = alloca i32*, align 64 +; IS__TUNIT_NPM-NEXT: [[PTR:%.*]] = alloca i32, align 128 +; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8* +; IS__TUNIT_NPM-NEXT: store i32 42, i32* [[B]], align 32 +; IS__TUNIT_NPM-NEXT: store i32* [[B]], i32** [[C]], align 64 +; IS__TUNIT_NPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t1_callback_broker(i32* noalias align 536870912 null, i32* noalias nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nonnull bitcast (void (i32*, i32*, i32*, i64, i32**)* @t1_callback_callee to void (i32*, i32*, ...)*), i32* noalias nocapture align 256 [[A]], i64 undef, i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C]]) +; IS__TUNIT_NPM-NEXT: ret void +; +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@t1_caller +; IS__CGSCC_OPM-SAME: (i32* noalias [[A:%.*]]) +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: [[B:%.*]] = alloca i32, align 32 +; IS__CGSCC_OPM-NEXT: [[C:%.*]] = alloca i32*, align 64 +; IS__CGSCC_OPM-NEXT: [[PTR:%.*]] = alloca i32, align 128 +; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8* +; IS__CGSCC_OPM-NEXT: store i32 42, i32* [[B]], align 32 +; IS__CGSCC_OPM-NEXT: store i32* [[B]], i32** [[C]], align 64 +; IS__CGSCC_OPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t1_callback_broker(i32* noalias align 536870912 null, i32* nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, i64, i32**)* @t1_callback_callee to void (i32*, i32*, ...)*), i32* [[A]], i64 99, i32** nonnull align 64 dereferenceable(8) [[C]]) +; IS__CGSCC_OPM-NEXT: ret void +; +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@t1_caller +; IS__CGSCC_NPM-SAME: (i32* noalias nocapture align 256 [[A:%.*]]) +; IS__CGSCC_NPM-NEXT: entry: +; IS__CGSCC_NPM-NEXT: [[B:%.*]] = alloca i32, align 32 +; IS__CGSCC_NPM-NEXT: [[C:%.*]] = alloca i32*, align 64 +; IS__CGSCC_NPM-NEXT: [[PTR:%.*]] = alloca i32, align 128 +; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8* +; IS__CGSCC_NPM-NEXT: store i32 42, i32* [[B]], align 32 +; IS__CGSCC_NPM-NEXT: store i32* [[B]], i32** [[C]], align 64 +; IS__CGSCC_NPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t1_callback_broker(i32* noalias align 536870912 null, i32* noalias nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, i64, i32**)* @t1_callback_callee to void (i32*, i32*, ...)*), i32* noalias nocapture align 256 [[A]], i64 99, i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C]]) +; IS__CGSCC_NPM-NEXT: ret void ; entry: %b = alloca i32, align 32 @@ -95,14 +186,33 @@ entry: ; Note that the first two arguments are provided by the callback_broker according to the callback in !1 below! ; The others are annotated with alignment information, amongst others, or even replaced by the constants passed to the call. define internal void @t1_callback_callee(i32* %is_not_null, i32* %ptr, i32* %a, i64 %b, i32** %c) { -; CHECK-LABEL: define {{[^@]+}}@t1_callback_callee -; CHECK-SAME: (i32* nocapture nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* noalias nocapture align 256 [[A:%.*]], i64 [[B:%.*]], i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) -; CHECK-NEXT: entry: -; CHECK-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8 -; CHECK-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4 -; CHECK-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64 -; CHECK-NEXT: tail call void @t1_check(i32* nocapture align 256 [[A]], i64 99, i32* [[TMP0]]) -; CHECK-NEXT: ret void +; +; IS________OPM-LABEL: define {{[^@]+}}@t1_callback_callee +; IS________OPM-SAME: (i32* nocapture nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* nocapture align 256 [[A:%.*]], i64 [[B:%.*]], i32** nocapture nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) +; IS________OPM-NEXT: entry: +; IS________OPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8 +; IS________OPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4 +; IS________OPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64 +; IS________OPM-NEXT: tail call void @t1_check(i32* nocapture align 256 [[A]], i64 99, i32* [[TMP0]]) +; IS________OPM-NEXT: ret void +; +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@t1_callback_callee +; IS__TUNIT_NPM-SAME: (i32* nocapture nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* noalias nocapture align 256 [[A:%.*]], i64 [[B:%.*]], i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) +; IS__TUNIT_NPM-NEXT: entry: +; IS__TUNIT_NPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8 +; IS__TUNIT_NPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4 +; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64 +; IS__TUNIT_NPM-NEXT: tail call void @t1_check(i32* nocapture align 256 [[A]], i64 99, i32* [[TMP0]]) +; IS__TUNIT_NPM-NEXT: ret void +; +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@t1_callback_callee +; IS__CGSCC_NPM-SAME: (i32* nocapture nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* nocapture align 256 [[A:%.*]], i64 [[B:%.*]], i32** nocapture nonnull readonly align 8 dereferenceable(8) [[C:%.*]]) +; IS__CGSCC_NPM-NEXT: entry: +; IS__CGSCC_NPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8 +; IS__CGSCC_NPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4 +; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 8 +; IS__CGSCC_NPM-NEXT: tail call void @t1_check(i32* nocapture align 256 [[A]], i64 99, i32* [[TMP0]]) +; IS__CGSCC_NPM-NEXT: ret void ; entry: %ptr_val = load i32, i32* %ptr, align 8 @@ -121,17 +231,53 @@ declare !callback !0 void @t1_callback_broker(i32* nocapture , i32* nocapture , ; Similar to test 1 but checking that the noalias is only placed if potential synchronization through @t2_check is preserved. define void @t2_caller(i32* noalias %a) { -; CHECK-LABEL: define {{[^@]+}}@t2_caller -; CHECK-SAME: (i32* noalias nocapture align 256 [[A:%.*]]) -; CHECK-NEXT: entry: -; CHECK-NEXT: [[B:%.*]] = alloca i32, align 32 -; CHECK-NEXT: [[C:%.*]] = alloca i32*, align 64 -; CHECK-NEXT: [[PTR:%.*]] = alloca i32, align 128 -; CHECK-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8* -; CHECK-NEXT: store i32 42, i32* [[B]], align 32 -; CHECK-NEXT: store i32* [[B]], i32** [[C]], align 64 -; CHECK-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t2_callback_broker(i32* noalias align 536870912 null, i32* noalias nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nonnull bitcast (void (i32*, i32*, i32*, i64, i32**)* @t2_callback_callee to void (i32*, i32*, ...)*), i32* noalias nocapture align 256 [[A]], i64 undef, i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C]]) -; CHECK-NEXT: ret void +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@t2_caller +; IS__TUNIT_OPM-SAME: (i32* noalias nocapture align 256 [[A:%.*]]) +; IS__TUNIT_OPM-NEXT: entry: +; IS__TUNIT_OPM-NEXT: [[B:%.*]] = alloca i32, align 32 +; IS__TUNIT_OPM-NEXT: [[C:%.*]] = alloca i32*, align 64 +; IS__TUNIT_OPM-NEXT: [[PTR:%.*]] = alloca i32, align 128 +; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8* +; IS__TUNIT_OPM-NEXT: store i32 42, i32* [[B]], align 32 +; IS__TUNIT_OPM-NEXT: store i32* [[B]], i32** [[C]], align 64 +; IS__TUNIT_OPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t2_callback_broker(i32* noalias align 536870912 null, i32* nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nonnull bitcast (void (i32*, i32*, i32*, i64, i32**)* @t2_callback_callee to void (i32*, i32*, ...)*), i32* nocapture align 256 [[A]], i64 undef, i32** nocapture nonnull readonly align 64 dereferenceable(8) [[C]]) +; IS__TUNIT_OPM-NEXT: ret void +; +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@t2_caller +; IS__TUNIT_NPM-SAME: (i32* noalias nocapture align 256 [[A:%.*]]) +; IS__TUNIT_NPM-NEXT: entry: +; IS__TUNIT_NPM-NEXT: [[B:%.*]] = alloca i32, align 32 +; IS__TUNIT_NPM-NEXT: [[C:%.*]] = alloca i32*, align 64 +; IS__TUNIT_NPM-NEXT: [[PTR:%.*]] = alloca i32, align 128 +; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8* +; IS__TUNIT_NPM-NEXT: store i32 42, i32* [[B]], align 32 +; IS__TUNIT_NPM-NEXT: store i32* [[B]], i32** [[C]], align 64 +; IS__TUNIT_NPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t2_callback_broker(i32* noalias align 536870912 null, i32* noalias nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nonnull bitcast (void (i32*, i32*, i32*, i64, i32**)* @t2_callback_callee to void (i32*, i32*, ...)*), i32* noalias nocapture align 256 [[A]], i64 undef, i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C]]) +; IS__TUNIT_NPM-NEXT: ret void +; +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@t2_caller +; IS__CGSCC_OPM-SAME: (i32* noalias [[A:%.*]]) +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: [[B:%.*]] = alloca i32, align 32 +; IS__CGSCC_OPM-NEXT: [[C:%.*]] = alloca i32*, align 64 +; IS__CGSCC_OPM-NEXT: [[PTR:%.*]] = alloca i32, align 128 +; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8* +; IS__CGSCC_OPM-NEXT: store i32 42, i32* [[B]], align 32 +; IS__CGSCC_OPM-NEXT: store i32* [[B]], i32** [[C]], align 64 +; IS__CGSCC_OPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t2_callback_broker(i32* noalias align 536870912 null, i32* nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, i64, i32**)* @t2_callback_callee to void (i32*, i32*, ...)*), i32* [[A]], i64 99, i32** nonnull align 64 dereferenceable(8) [[C]]) +; IS__CGSCC_OPM-NEXT: ret void +; +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@t2_caller +; IS__CGSCC_NPM-SAME: (i32* noalias nocapture align 256 [[A:%.*]]) +; IS__CGSCC_NPM-NEXT: entry: +; IS__CGSCC_NPM-NEXT: [[B:%.*]] = alloca i32, align 32 +; IS__CGSCC_NPM-NEXT: [[C:%.*]] = alloca i32*, align 64 +; IS__CGSCC_NPM-NEXT: [[PTR:%.*]] = alloca i32, align 128 +; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8* +; IS__CGSCC_NPM-NEXT: store i32 42, i32* [[B]], align 32 +; IS__CGSCC_NPM-NEXT: store i32* [[B]], i32** [[C]], align 64 +; IS__CGSCC_NPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t2_callback_broker(i32* noalias align 536870912 null, i32* noalias nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, i64, i32**)* @t2_callback_callee to void (i32*, i32*, ...)*), i32* noalias nocapture align 256 [[A]], i64 99, i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C]]) +; IS__CGSCC_NPM-NEXT: ret void ; entry: %b = alloca i32, align 32 @@ -149,14 +295,33 @@ entry: ; ; FIXME: We should derive noalias for %a and add a "fake use" of %a in all potentially synchronizing calls. define internal void @t2_callback_callee(i32* %is_not_null, i32* %ptr, i32* %a, i64 %b, i32** %c) { -; CHECK-LABEL: define {{[^@]+}}@t2_callback_callee -; CHECK-SAME: (i32* nocapture nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* nocapture align 256 [[A:%.*]], i64 [[B:%.*]], i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) -; CHECK-NEXT: entry: -; CHECK-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8 -; CHECK-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4 -; CHECK-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64 -; CHECK-NEXT: tail call void @t2_check(i32* nocapture align 256 [[A]], i64 99, i32* [[TMP0]]) -; CHECK-NEXT: ret void +; +; IS________OPM-LABEL: define {{[^@]+}}@t2_callback_callee +; IS________OPM-SAME: (i32* nocapture nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* nocapture align 256 [[A:%.*]], i64 [[B:%.*]], i32** nocapture nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) +; IS________OPM-NEXT: entry: +; IS________OPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8 +; IS________OPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4 +; IS________OPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64 +; IS________OPM-NEXT: tail call void @t2_check(i32* nocapture align 256 [[A]], i64 99, i32* [[TMP0]]) +; IS________OPM-NEXT: ret void +; +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@t2_callback_callee +; IS__TUNIT_NPM-SAME: (i32* nocapture nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* nocapture align 256 [[A:%.*]], i64 [[B:%.*]], i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) +; IS__TUNIT_NPM-NEXT: entry: +; IS__TUNIT_NPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8 +; IS__TUNIT_NPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4 +; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64 +; IS__TUNIT_NPM-NEXT: tail call void @t2_check(i32* nocapture align 256 [[A]], i64 99, i32* [[TMP0]]) +; IS__TUNIT_NPM-NEXT: ret void +; +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@t2_callback_callee +; IS__CGSCC_NPM-SAME: (i32* nocapture nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* nocapture align 256 [[A:%.*]], i64 [[B:%.*]], i32** nocapture nonnull readonly align 8 dereferenceable(8) [[C:%.*]]) +; IS__CGSCC_NPM-NEXT: entry: +; IS__CGSCC_NPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8 +; IS__CGSCC_NPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4 +; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 8 +; IS__CGSCC_NPM-NEXT: tail call void @t2_check(i32* nocapture align 256 [[A]], i64 99, i32* [[TMP0]]) +; IS__CGSCC_NPM-NEXT: ret void ; entry: %ptr_val = load i32, i32* %ptr, align 8 @@ -175,18 +340,57 @@ declare !callback !0 void @t2_callback_broker(i32* nocapture , i32* nocapture , ; Basically test 2 with the casted callback callee used twice. define void @t3_caller(i32* noalias %a) { -; CHECK-LABEL: define {{[^@]+}}@t3_caller -; CHECK-SAME: (i32* noalias nocapture align 256 [[A:%.*]]) -; CHECK-NEXT: entry: -; CHECK-NEXT: [[B:%.*]] = alloca i32, align 32 -; CHECK-NEXT: [[C:%.*]] = alloca i32*, align 64 -; CHECK-NEXT: [[PTR:%.*]] = alloca i32, align 128 -; CHECK-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8* -; CHECK-NEXT: store i32 42, i32* [[B]], align 32 -; CHECK-NEXT: store i32* [[B]], i32** [[C]], align 64 -; CHECK-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t3_callback_broker(i32* noalias align 536870912 null, i32* noalias nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nonnull bitcast (void (i32*, i32*, i32*, i64, i32**)* @t3_callback_callee to void (i32*, i32*, ...)*), i32* noalias nocapture align 256 [[A]], i64 undef, i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C]]) -; CHECK-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t3_callback_broker(i32* noalias align 536870912 null, i32* noalias nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nonnull bitcast (void (i32*, i32*, i32*, i64, i32**)* @t3_callback_callee to void (i32*, i32*, ...)*), i32* noalias nocapture align 256 [[A]], i64 undef, i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C]]) -; CHECK-NEXT: ret void +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@t3_caller +; IS__TUNIT_OPM-SAME: (i32* noalias nocapture align 256 [[A:%.*]]) +; IS__TUNIT_OPM-NEXT: entry: +; IS__TUNIT_OPM-NEXT: [[B:%.*]] = alloca i32, align 32 +; IS__TUNIT_OPM-NEXT: [[C:%.*]] = alloca i32*, align 64 +; IS__TUNIT_OPM-NEXT: [[PTR:%.*]] = alloca i32, align 128 +; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8* +; IS__TUNIT_OPM-NEXT: store i32 42, i32* [[B]], align 32 +; IS__TUNIT_OPM-NEXT: store i32* [[B]], i32** [[C]], align 64 +; IS__TUNIT_OPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t3_callback_broker(i32* noalias align 536870912 null, i32* nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nonnull bitcast (void (i32*, i32*, i32*, i64, i32**)* @t3_callback_callee to void (i32*, i32*, ...)*), i32* nocapture align 256 [[A]], i64 undef, i32** nocapture nonnull readonly align 64 dereferenceable(8) [[C]]) +; IS__TUNIT_OPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t3_callback_broker(i32* noalias align 536870912 null, i32* nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nonnull bitcast (void (i32*, i32*, i32*, i64, i32**)* @t3_callback_callee to void (i32*, i32*, ...)*), i32* nocapture align 256 [[A]], i64 undef, i32** nocapture nonnull readonly align 64 dereferenceable(8) [[C]]) +; IS__TUNIT_OPM-NEXT: ret void +; +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@t3_caller +; IS__TUNIT_NPM-SAME: (i32* noalias nocapture align 256 [[A:%.*]]) +; IS__TUNIT_NPM-NEXT: entry: +; IS__TUNIT_NPM-NEXT: [[B:%.*]] = alloca i32, align 32 +; IS__TUNIT_NPM-NEXT: [[C:%.*]] = alloca i32*, align 64 +; IS__TUNIT_NPM-NEXT: [[PTR:%.*]] = alloca i32, align 128 +; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8* +; IS__TUNIT_NPM-NEXT: store i32 42, i32* [[B]], align 32 +; IS__TUNIT_NPM-NEXT: store i32* [[B]], i32** [[C]], align 64 +; IS__TUNIT_NPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t3_callback_broker(i32* noalias align 536870912 null, i32* noalias nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nonnull bitcast (void (i32*, i32*, i32*, i64, i32**)* @t3_callback_callee to void (i32*, i32*, ...)*), i32* noalias nocapture align 256 [[A]], i64 undef, i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C]]) +; IS__TUNIT_NPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t3_callback_broker(i32* noalias align 536870912 null, i32* noalias nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nonnull bitcast (void (i32*, i32*, i32*, i64, i32**)* @t3_callback_callee to void (i32*, i32*, ...)*), i32* noalias nocapture align 256 [[A]], i64 undef, i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C]]) +; IS__TUNIT_NPM-NEXT: ret void +; +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@t3_caller +; IS__CGSCC_OPM-SAME: (i32* noalias [[A:%.*]]) +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: [[B:%.*]] = alloca i32, align 32 +; IS__CGSCC_OPM-NEXT: [[C:%.*]] = alloca i32*, align 64 +; IS__CGSCC_OPM-NEXT: [[PTR:%.*]] = alloca i32, align 128 +; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8* +; IS__CGSCC_OPM-NEXT: store i32 42, i32* [[B]], align 32 +; IS__CGSCC_OPM-NEXT: store i32* [[B]], i32** [[C]], align 64 +; IS__CGSCC_OPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t3_callback_broker(i32* noalias align 536870912 null, i32* nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, i64, i32**)* @t3_callback_callee to void (i32*, i32*, ...)*), i32* [[A]], i64 99, i32** nonnull align 64 dereferenceable(8) [[C]]) +; IS__CGSCC_OPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t3_callback_broker(i32* noalias align 536870912 null, i32* nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, i64, i32**)* @t3_callback_callee to void (i32*, i32*, ...)*), i32* [[A]], i64 99, i32** nonnull align 64 dereferenceable(8) [[C]]) +; IS__CGSCC_OPM-NEXT: ret void +; +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@t3_caller +; IS__CGSCC_NPM-SAME: (i32* noalias nocapture align 256 [[A:%.*]]) +; IS__CGSCC_NPM-NEXT: entry: +; IS__CGSCC_NPM-NEXT: [[B:%.*]] = alloca i32, align 32 +; IS__CGSCC_NPM-NEXT: [[C:%.*]] = alloca i32*, align 64 +; IS__CGSCC_NPM-NEXT: [[PTR:%.*]] = alloca i32, align 128 +; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8* +; IS__CGSCC_NPM-NEXT: store i32 42, i32* [[B]], align 32 +; IS__CGSCC_NPM-NEXT: store i32* [[B]], i32** [[C]], align 64 +; IS__CGSCC_NPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t3_callback_broker(i32* noalias align 536870912 null, i32* noalias nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, i64, i32**)* @t3_callback_callee to void (i32*, i32*, ...)*), i32* noalias nocapture align 256 [[A]], i64 99, i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C]]) +; IS__CGSCC_NPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t3_callback_broker(i32* noalias align 536870912 null, i32* noalias nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, i64, i32**)* @t3_callback_callee to void (i32*, i32*, ...)*), i32* noalias nocapture align 256 [[A]], i64 99, i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C]]) +; IS__CGSCC_NPM-NEXT: ret void ; entry: %b = alloca i32, align 32 @@ -205,14 +409,33 @@ entry: ; ; FIXME: We should derive noalias for %a and add a "fake use" of %a in all potentially synchronizing calls. define internal void @t3_callback_callee(i32* %is_not_null, i32* %ptr, i32* %a, i64 %b, i32** %c) { -; CHECK-LABEL: define {{[^@]+}}@t3_callback_callee -; CHECK-SAME: (i32* nocapture nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* nocapture align 256 [[A:%.*]], i64 [[B:%.*]], i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) -; CHECK-NEXT: entry: -; CHECK-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8 -; CHECK-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4 -; CHECK-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64 -; CHECK-NEXT: tail call void @t3_check(i32* nocapture align 256 [[A]], i64 99, i32* [[TMP0]]) -; CHECK-NEXT: ret void +; +; IS________OPM-LABEL: define {{[^@]+}}@t3_callback_callee +; IS________OPM-SAME: (i32* nocapture nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* nocapture align 256 [[A:%.*]], i64 [[B:%.*]], i32** nocapture nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) +; IS________OPM-NEXT: entry: +; IS________OPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8 +; IS________OPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4 +; IS________OPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64 +; IS________OPM-NEXT: tail call void @t3_check(i32* nocapture align 256 [[A]], i64 99, i32* [[TMP0]]) +; IS________OPM-NEXT: ret void +; +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@t3_callback_callee +; IS__TUNIT_NPM-SAME: (i32* nocapture nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* nocapture align 256 [[A:%.*]], i64 [[B:%.*]], i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) +; IS__TUNIT_NPM-NEXT: entry: +; IS__TUNIT_NPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8 +; IS__TUNIT_NPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4 +; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64 +; IS__TUNIT_NPM-NEXT: tail call void @t3_check(i32* nocapture align 256 [[A]], i64 99, i32* [[TMP0]]) +; IS__TUNIT_NPM-NEXT: ret void +; +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@t3_callback_callee +; IS__CGSCC_NPM-SAME: (i32* nocapture nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* nocapture align 256 [[A:%.*]], i64 [[B:%.*]], i32** nocapture nonnull readonly align 8 dereferenceable(8) [[C:%.*]]) +; IS__CGSCC_NPM-NEXT: entry: +; IS__CGSCC_NPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8 +; IS__CGSCC_NPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4 +; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 8 +; IS__CGSCC_NPM-NEXT: tail call void @t3_check(i32* nocapture align 256 [[A]], i64 99, i32* [[TMP0]]) +; IS__CGSCC_NPM-NEXT: ret void ; entry: %ptr_val = load i32, i32* %ptr, align 8 diff --git a/llvm/test/Transforms/Attributor/dereferenceable-1.ll b/llvm/test/Transforms/Attributor/dereferenceable-1.ll index 7a6de53f3f69..a1da5fbe2d7c 100644 --- a/llvm/test/Transforms/Attributor/dereferenceable-1.ll +++ b/llvm/test/Transforms/Attributor/dereferenceable-1.ll @@ -1,16 +1,22 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes -; RUN: opt -attributor -attributor-manifest-internal --attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=16 -S < %s | FileCheck %s --check-prefix=ATTRIBUTOR +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=16 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=16 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 ; FIXME: Figure out why we need 16 iterations here. -; UTC_ARGS: --disable - declare void @deref_phi_user(i32* %a); ; TEST 1 ; take mininimum of return values ; define i32* @test1(i32* dereferenceable(4) %0, double* dereferenceable(8) %1, i1 zeroext %2) local_unnamed_addr { -; ATTRIBUTOR: define nonnull dereferenceable(4) i32* @test1(i32* nofree nonnull readnone dereferenceable(4) "no-capture-maybe-returned" %0, double* nofree nonnull readnone dereferenceable(8) "no-capture-maybe-returned" %1, i1 zeroext %2) +; CHECK-LABEL: define {{[^@]+}}@test1 +; CHECK-SAME: (i32* nofree nonnull readnone dereferenceable(4) "no-capture-maybe-returned" [[TMP0:%.*]], double* nofree nonnull readnone dereferenceable(8) "no-capture-maybe-returned" [[TMP1:%.*]], i1 zeroext [[TMP2:%.*]]) local_unnamed_addr +; CHECK-NEXT: [[TMP4:%.*]] = bitcast double* [[TMP1]] to i32* +; CHECK-NEXT: [[TMP5:%.*]] = select i1 [[TMP2]], i32* [[TMP0]], i32* [[TMP4]] +; CHECK-NEXT: ret i32* [[TMP5]] +; %4 = bitcast double* %1 to i32* %5 = select i1 %2, i32* %0, i32* %4 ret i32* %5 @@ -18,7 +24,12 @@ define i32* @test1(i32* dereferenceable(4) %0, double* dereferenceable(8) %1, i1 ; TEST 2 define i32* @test2(i32* dereferenceable_or_null(4) %0, double* dereferenceable(8) %1, i1 zeroext %2) local_unnamed_addr { -; ATTRIBUTOR: define dereferenceable_or_null(4) i32* @test2(i32* nofree readnone dereferenceable_or_null(4) "no-capture-maybe-returned" %0, double* nofree nonnull readnone dereferenceable(8) "no-capture-maybe-returned" %1, i1 zeroext %2) +; CHECK-LABEL: define {{[^@]+}}@test2 +; CHECK-SAME: (i32* nofree readnone dereferenceable_or_null(4) "no-capture-maybe-returned" [[TMP0:%.*]], double* nofree nonnull readnone dereferenceable(8) "no-capture-maybe-returned" [[TMP1:%.*]], i1 zeroext [[TMP2:%.*]]) local_unnamed_addr +; CHECK-NEXT: [[TMP4:%.*]] = bitcast double* [[TMP1]] to i32* +; CHECK-NEXT: [[TMP5:%.*]] = select i1 [[TMP2]], i32* [[TMP0]], i32* [[TMP4]] +; CHECK-NEXT: ret i32* [[TMP5]] +; %4 = bitcast double* %1 to i32* %5 = select i1 %2, i32* %0, i32* %4 ret i32* %5 @@ -27,19 +38,33 @@ define i32* @test2(i32* dereferenceable_or_null(4) %0, double* dereferenceable(8 ; TEST 3 ; GEP inbounds define i32* @test3_1(i32* dereferenceable(8) %0) local_unnamed_addr { -; ATTRIBUTOR: define nonnull dereferenceable(4) i32* @test3_1(i32* nofree nonnull readnone dereferenceable(8) "no-capture-maybe-returned" %0) +; CHECK-LABEL: define {{[^@]+}}@test3_1 +; CHECK-SAME: (i32* nofree nonnull readnone dereferenceable(8) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr +; CHECK-NEXT: [[RET:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 1 +; CHECK-NEXT: ret i32* [[RET]] +; %ret = getelementptr inbounds i32, i32* %0, i64 1 ret i32* %ret } define i32* @test3_2(i32* dereferenceable_or_null(32) %0) local_unnamed_addr { -; ATTRIBUTOR: define nonnull dereferenceable(16) i32* @test3_2(i32* nofree readnone dereferenceable_or_null(32) "no-capture-maybe-returned" %0) +; CHECK-LABEL: define {{[^@]+}}@test3_2 +; CHECK-SAME: (i32* nofree readnone dereferenceable_or_null(32) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr +; CHECK-NEXT: [[RET:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 4 +; CHECK-NEXT: ret i32* [[RET]] +; %ret = getelementptr inbounds i32, i32* %0, i64 4 ret i32* %ret } define i32* @test3_3(i32* dereferenceable(8) %0, i32* dereferenceable(16) %1, i1 %2) local_unnamed_addr { -; ATTRIBUTOR: define nonnull dereferenceable(4) i32* @test3_3(i32* nofree nonnull readnone dereferenceable(8) "no-capture-maybe-returned" %0, i32* nofree nonnull readnone dereferenceable(16) "no-capture-maybe-returned" %1, i1 %2) local_unnamed_addr +; CHECK-LABEL: define {{[^@]+}}@test3_3 +; CHECK-SAME: (i32* nofree nonnull readnone dereferenceable(8) "no-capture-maybe-returned" [[TMP0:%.*]], i32* nofree nonnull readnone dereferenceable(16) "no-capture-maybe-returned" [[TMP1:%.*]], i1 [[TMP2:%.*]]) local_unnamed_addr +; CHECK-NEXT: [[RET1:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 1 +; CHECK-NEXT: [[RET2:%.*]] = getelementptr inbounds i32, i32* [[TMP1]], i64 2 +; CHECK-NEXT: [[RET:%.*]] = select i1 [[TMP2]], i32* [[RET1]], i32* [[RET2]] +; CHECK-NEXT: ret i32* [[RET]] +; %ret1 = getelementptr inbounds i32, i32* %0, i64 1 %ret2 = getelementptr inbounds i32, i32* %1, i64 2 %ret = select i1 %2, i32* %ret1, i32* %ret2 @@ -50,20 +75,44 @@ define i32* @test3_3(i32* dereferenceable(8) %0, i32* dereferenceable(16) %1, i1 ; Better than known in IR. define dereferenceable(4) i32* @test4(i32* dereferenceable(8) %0) local_unnamed_addr { -; ATTRIBUTOR: define nonnull dereferenceable(8) i32* @test4(i32* nofree nonnull readnone returned dereferenceable(8) "no-capture-maybe-returned" %0) +; CHECK-LABEL: define {{[^@]+}}@test4 +; CHECK-SAME: (i32* nofree nonnull readnone returned dereferenceable(8) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr +; CHECK-NEXT: ret i32* [[TMP0]] +; ret i32* %0 } ; TEST 5 ; loop in which dereferenceabily "grows" define void @deref_phi_growing(i32* dereferenceable(4000) %a) { +; CHECK-LABEL: define {{[^@]+}}@deref_phi_growing +; CHECK-SAME: (i32* nonnull dereferenceable(4000) [[A:%.*]]) +; CHECK-NEXT: entry: +; CHECK-NEXT: br label [[FOR_COND:%.*]] +; CHECK: for.cond: +; CHECK-NEXT: [[I_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_INC:%.*]] ] +; CHECK-NEXT: [[A_ADDR_0:%.*]] = phi i32* [ [[A]], [[ENTRY]] ], [ [[INCDEC_PTR:%.*]], [[FOR_INC]] ] +; CHECK-NEXT: call void @deref_phi_user(i32* nonnull dereferenceable(4000) [[A_ADDR_0]]) +; CHECK-NEXT: [[TMP:%.*]] = load i32, i32* [[A_ADDR_0]], align 4 +; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_0]], [[TMP]] +; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]] +; CHECK: for.cond.cleanup: +; CHECK-NEXT: br label [[FOR_END:%.*]] +; CHECK: for.body: +; CHECK-NEXT: br label [[FOR_INC]] +; CHECK: for.inc: +; CHECK-NEXT: [[INCDEC_PTR]] = getelementptr inbounds i32, i32* [[A_ADDR_0]], i64 -1 +; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_0]], 1 +; CHECK-NEXT: br label [[FOR_COND]] +; CHECK: for.end: +; CHECK-NEXT: ret void +; entry: br label %for.cond for.cond: ; preds = %for.inc, %entry %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ] %a.addr.0 = phi i32* [ %a, %entry ], [ %incdec.ptr, %for.inc ] -; ATTRIBUTOR: call void @deref_phi_user(i32* nonnull dereferenceable(4000) %a.addr.0) call void @deref_phi_user(i32* %a.addr.0) %tmp = load i32, i32* %a.addr.0, align 4 %cmp = icmp slt i32 %i.0, %tmp @@ -87,13 +136,34 @@ for.end: ; preds = %for.cond.cleanup ; TEST 6 ; loop in which dereferenceabily "shrinks" define void @deref_phi_shrinking(i32* dereferenceable(4000) %a) { +; CHECK-LABEL: define {{[^@]+}}@deref_phi_shrinking +; CHECK-SAME: (i32* nonnull dereferenceable(4000) [[A:%.*]]) +; CHECK-NEXT: entry: +; CHECK-NEXT: br label [[FOR_COND:%.*]] +; CHECK: for.cond: +; CHECK-NEXT: [[I_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_INC:%.*]] ] +; CHECK-NEXT: [[A_ADDR_0:%.*]] = phi i32* [ [[A]], [[ENTRY]] ], [ [[INCDEC_PTR:%.*]], [[FOR_INC]] ] +; CHECK-NEXT: call void @deref_phi_user(i32* nonnull [[A_ADDR_0]]) +; CHECK-NEXT: [[TMP:%.*]] = load i32, i32* [[A_ADDR_0]], align 4 +; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_0]], [[TMP]] +; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]] +; CHECK: for.cond.cleanup: +; CHECK-NEXT: br label [[FOR_END:%.*]] +; CHECK: for.body: +; CHECK-NEXT: br label [[FOR_INC]] +; CHECK: for.inc: +; CHECK-NEXT: [[INCDEC_PTR]] = getelementptr inbounds i32, i32* [[A_ADDR_0]], i64 1 +; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_0]], 1 +; CHECK-NEXT: br label [[FOR_COND]] +; CHECK: for.end: +; CHECK-NEXT: ret void +; entry: br label %for.cond for.cond: ; preds = %for.inc, %entry %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ] %a.addr.0 = phi i32* [ %a, %entry ], [ %incdec.ptr, %for.inc ] -; ATTRIBUTOR: call void @deref_phi_user(i32* nonnull %a.addr.0) call void @deref_phi_user(i32* %a.addr.0) %tmp = load i32, i32* %a.addr.0, align 4 %cmp = icmp slt i32 %i.0, %tmp @@ -119,96 +189,108 @@ for.end: ; preds = %for.cond.cleanup declare i32* @unkown_ptr() willreturn nounwind declare i32 @unkown_f(i32*) willreturn nounwind define i32* @f7_0(i32* %ptr) { -; ATTRIBUTOR: define nonnull dereferenceable(8) i32* @f7_0(i32* nonnull returned dereferenceable(8) %ptr) +; CHECK-LABEL: define {{[^@]+}}@f7_0 +; CHECK-SAME: (i32* nonnull returned dereferenceable(8) [[PTR:%.*]]) +; CHECK-NEXT: [[T:%.*]] = tail call i32 @unkown_f(i32* nonnull dereferenceable(8) [[PTR]]) +; CHECK-NEXT: ret i32* [[PTR]] +; %T = tail call i32 @unkown_f(i32* dereferenceable(8) %ptr) ret i32* %ptr } -; ATTRIBUTOR: define void @f7_1(i32* nonnull align 4 dereferenceable(4) %ptr, i1 %c) define void @f7_1(i32* %ptr, i1 %c) { - -; ATTRIBUTOR: %A = tail call i32 @unkown_f(i32* nonnull align 4 dereferenceable(4) %ptr) +; CHECK-LABEL: define {{[^@]+}}@f7_1 +; CHECK-SAME: (i32* nonnull align 4 dereferenceable(4) [[PTR:%.*]], i1 [[C:%.*]]) +; CHECK-NEXT: [[A:%.*]] = tail call i32 @unkown_f(i32* nonnull align 4 dereferenceable(4) [[PTR]]) +; CHECK-NEXT: [[B:%.*]] = tail call i32 @unkown_f(i32* nonnull align 4 dereferenceable(4) [[PTR]]) +; CHECK-NEXT: br i1 [[C]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] +; CHECK: if.true: +; CHECK-NEXT: [[C:%.*]] = tail call i32 @unkown_f(i32* nonnull align 4 dereferenceable(8) [[PTR]]) +; CHECK-NEXT: [[D:%.*]] = tail call i32 @unkown_f(i32* nonnull align 4 dereferenceable(8) [[PTR]]) +; CHECK-NEXT: [[E:%.*]] = tail call i32 @unkown_f(i32* nonnull align 4 dereferenceable(8) [[PTR]]) +; CHECK-NEXT: ret void +; CHECK: if.false: +; CHECK-NEXT: ret void +; %A = tail call i32 @unkown_f(i32* %ptr) - %ptr.0 = load i32, i32* %ptr ; deref 4 hold - ; FIXME: this should be %B = tail call i32 @unkown_f(i32* nonnull dereferenceable(4) %ptr) -; ATTRIBUTOR: %B = tail call i32 @unkown_f(i32* nonnull align 4 dereferenceable(4) %ptr) %B = tail call i32 @unkown_f(i32* dereferenceable(1) %ptr) - br i1%c, label %if.true, label %if.false if.true: -; ATTRIBUTOR: %C = tail call i32 @unkown_f(i32* nonnull align 4 dereferenceable(8) %ptr) %C = tail call i32 @unkown_f(i32* %ptr) - -; ATTRIBUTOR: %D = tail call i32 @unkown_f(i32* nonnull align 4 dereferenceable(8) %ptr) %D = tail call i32 @unkown_f(i32* dereferenceable(8) %ptr) - -; ATTRIBUTOR: %E = tail call i32 @unkown_f(i32* nonnull align 4 dereferenceable(8) %ptr) %E = tail call i32 @unkown_f(i32* %ptr) - ret void - if.false: ret void } -; ATTRIBUTOR: define void @f7_2(i1 %c) define void @f7_2(i1 %c) { - +; CHECK-LABEL: define {{[^@]+}}@f7_2 +; CHECK-SAME: (i1 [[C:%.*]]) +; CHECK-NEXT: [[PTR:%.*]] = tail call nonnull align 4 dereferenceable(4) i32* @unkown_ptr() +; CHECK-NEXT: [[A:%.*]] = tail call i32 @unkown_f(i32* nonnull align 4 dereferenceable(4) [[PTR]]) +; CHECK-NEXT: [[B:%.*]] = tail call i32 @unkown_f(i32* nonnull align 4 dereferenceable(4) [[PTR]]) +; CHECK-NEXT: br i1 [[C]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] +; CHECK: if.true: +; CHECK-NEXT: [[C:%.*]] = tail call i32 @unkown_f(i32* nonnull align 4 dereferenceable(8) [[PTR]]) +; CHECK-NEXT: [[D:%.*]] = tail call i32 @unkown_f(i32* nonnull align 4 dereferenceable(8) [[PTR]]) +; CHECK-NEXT: [[E:%.*]] = tail call i32 @unkown_f(i32* nonnull align 4 dereferenceable(8) [[PTR]]) +; CHECK-NEXT: ret void +; CHECK: if.false: +; CHECK-NEXT: ret void +; %ptr = tail call i32* @unkown_ptr() - -; ATTRIBUTOR: %A = tail call i32 @unkown_f(i32* nonnull align 4 dereferenceable(4) %ptr) %A = tail call i32 @unkown_f(i32* %ptr) - %arg_a.0 = load i32, i32* %ptr ; deref 4 hold - -; ATTRIBUTOR: %B = tail call i32 @unkown_f(i32* nonnull align 4 dereferenceable(4) %ptr) %B = tail call i32 @unkown_f(i32* dereferenceable(1) %ptr) - br i1%c, label %if.true, label %if.false if.true: - -; ATTRIBUTOR: %C = tail call i32 @unkown_f(i32* nonnull align 4 dereferenceable(8) %ptr) %C = tail call i32 @unkown_f(i32* %ptr) - -; ATTRIBUTOR: %D = tail call i32 @unkown_f(i32* nonnull align 4 dereferenceable(8) %ptr) %D = tail call i32 @unkown_f(i32* dereferenceable(8) %ptr) - %E = tail call i32 @unkown_f(i32* %ptr) -; ATTRIBUTOR: %E = tail call i32 @unkown_f(i32* nonnull align 4 dereferenceable(8) %ptr) - ret void - if.false: ret void } define i32* @f7_3() { -; ATTRIBUTOR: define nonnull align 16 dereferenceable(4) i32* @f7_3() +; CHECK-LABEL: define {{[^@]+}}@f7_3() +; CHECK-NEXT: [[PTR:%.*]] = tail call nonnull align 16 dereferenceable(4) i32* @unkown_ptr() +; CHECK-NEXT: store i32 10, i32* [[PTR]], align 16 +; CHECK-NEXT: ret i32* [[PTR]] +; %ptr = tail call i32* @unkown_ptr() store i32 10, i32* %ptr, align 16 ret i32* %ptr } -define i32* @test_for_minus_index(i32* %p) { ; FIXME: This should have a return dereferenceable(8) but we need to make sure it will work in loops as well. -; ATTRIBUTOR: define nonnull align 4 i32* @test_for_minus_index(i32* nofree nonnull writeonly align 4 "no-capture-maybe-returned" %p) +define i32* @test_for_minus_index(i32* %p) { +; CHECK-LABEL: define {{[^@]+}}@test_for_minus_index +; CHECK-SAME: (i32* nofree nonnull writeonly align 4 "no-capture-maybe-returned" [[P:%.*]]) +; CHECK-NEXT: [[Q:%.*]] = getelementptr inbounds i32, i32* [[P]], i32 -2 +; CHECK-NEXT: store i32 1, i32* [[Q]], align 4 +; CHECK-NEXT: ret i32* [[Q]] +; %q = getelementptr inbounds i32, i32* %p, i32 -2 store i32 1, i32* %q ret i32* %q } define void @deref_or_null_and_nonnull(i32* dereferenceable_or_null(100) %0) { -; ATTRIBUTOR: define void @deref_or_null_and_nonnull(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(100) %0) +; CHECK-LABEL: define {{[^@]+}}@deref_or_null_and_nonnull +; CHECK-SAME: (i32* nocapture nofree nonnull writeonly align 4 dereferenceable(100) [[TMP0:%.*]]) +; CHECK-NEXT: store i32 1, i32* [[TMP0]], align 4 +; CHECK-NEXT: ret void +; store i32 1, i32* %0 ret void } -; UTC_ARGS: --enable - ; TEST 8 ; Use Constant range in deereferenceable ; void g(int *p, long long int *range){ @@ -223,24 +305,24 @@ define void @deref_or_null_and_nonnull(i32* dereferenceable_or_null(100) %0) { ; } ; } -define internal void @fill_range_not_inbounds(i32* %p, i64 %start){ -; ATTRIBUTOR-LABEL: define {{[^@]+}}@fill_range_not_inbounds -; ATTRIBUTOR-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i64 [[START:%.*]]) -; ATTRIBUTOR-NEXT: entry: -; ATTRIBUTOR-NEXT: [[TMP0:%.*]] = add nsw i64 [[START]], 9 -; ATTRIBUTOR-NEXT: br label [[FOR_BODY:%.*]] -; ATTRIBUTOR: for.cond.cleanup: -; ATTRIBUTOR-NEXT: ret void -; ATTRIBUTOR: for.body: -; ATTRIBUTOR-NEXT: [[I_06:%.*]] = phi i64 [ [[START]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ] -; ATTRIBUTOR-NEXT: [[CONV:%.*]] = trunc i64 [[I_06]] to i32 -; ATTRIBUTOR-NEXT: [[ARRAYIDX:%.*]] = getelementptr i32, i32* [[P]], i64 [[I_06]] -; ATTRIBUTOR-NEXT: store i32 [[CONV]], i32* [[ARRAYIDX]], align 4 -; ATTRIBUTOR-NEXT: [[INC]] = add nsw i64 [[I_06]], 1 -; ATTRIBUTOR-NEXT: [[CMP:%.*]] = icmp slt i64 [[I_06]], [[TMP0]] -; ATTRIBUTOR-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_COND_CLEANUP:%.*]] -; ; NOTE: %p should not be dereferenceable +define internal void @fill_range_not_inbounds(i32* %p, i64 %start){ +; CHECK-LABEL: define {{[^@]+}}@fill_range_not_inbounds +; CHECK-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i64 [[START:%.*]]) +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = add nsw i64 [[START]], 9 +; CHECK-NEXT: br label [[FOR_BODY:%.*]] +; CHECK: for.cond.cleanup: +; CHECK-NEXT: ret void +; CHECK: for.body: +; CHECK-NEXT: [[I_06:%.*]] = phi i64 [ [[START]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ] +; CHECK-NEXT: [[CONV:%.*]] = trunc i64 [[I_06]] to i32 +; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr i32, i32* [[P]], i64 [[I_06]] +; CHECK-NEXT: store i32 [[CONV]], i32* [[ARRAYIDX]], align 4 +; CHECK-NEXT: [[INC]] = add nsw i64 [[I_06]], 1 +; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[I_06]], [[TMP0]] +; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_COND_CLEANUP:%.*]] +; entry: %0 = add nsw i64 %start, 9 br label %for.body @@ -257,24 +339,25 @@ for.body: ; preds = %entry, %for.body %cmp = icmp slt i64 %i.06, %0 br i1 %cmp, label %for.body, label %for.cond.cleanup } -define internal void @fill_range_inbounds(i32* %p, i64 %start){ -; ATTRIBUTOR-LABEL: define {{[^@]+}}@fill_range_inbounds -; ATTRIBUTOR-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i64 [[START:%.*]]) -; ATTRIBUTOR-NEXT: entry: -; ATTRIBUTOR-NEXT: [[TMP0:%.*]] = add nsw i64 [[START]], 9 -; ATTRIBUTOR-NEXT: br label [[FOR_BODY:%.*]] -; ATTRIBUTOR: for.cond.cleanup: -; ATTRIBUTOR-NEXT: ret void -; ATTRIBUTOR: for.body: -; ATTRIBUTOR-NEXT: [[I_06:%.*]] = phi i64 [ [[START]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ] -; ATTRIBUTOR-NEXT: [[CONV:%.*]] = trunc i64 [[I_06]] to i32 -; ATTRIBUTOR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 [[I_06]] -; ATTRIBUTOR-NEXT: store i32 [[CONV]], i32* [[ARRAYIDX]], align 4 -; ATTRIBUTOR-NEXT: [[INC]] = add nsw i64 [[I_06]], 1 -; ATTRIBUTOR-NEXT: [[CMP:%.*]] = icmp slt i64 [[I_06]], [[TMP0]] -; ATTRIBUTOR-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_COND_CLEANUP:%.*]] -; + ; FIXME: %p should be dereferenceable(40) +define internal void @fill_range_inbounds(i32* %p, i64 %start){ +; CHECK-LABEL: define {{[^@]+}}@fill_range_inbounds +; CHECK-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i64 [[START:%.*]]) +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = add nsw i64 [[START]], 9 +; CHECK-NEXT: br label [[FOR_BODY:%.*]] +; CHECK: for.cond.cleanup: +; CHECK-NEXT: ret void +; CHECK: for.body: +; CHECK-NEXT: [[I_06:%.*]] = phi i64 [ [[START]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ] +; CHECK-NEXT: [[CONV:%.*]] = trunc i64 [[I_06]] to i32 +; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 [[I_06]] +; CHECK-NEXT: store i32 [[CONV]], i32* [[ARRAYIDX]], align 4 +; CHECK-NEXT: [[INC]] = add nsw i64 [[I_06]], 1 +; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[I_06]], [[TMP0]] +; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_COND_CLEANUP:%.*]] +; entry: %0 = add nsw i64 %start, 9 br label %for.body @@ -293,13 +376,13 @@ for.body: ; preds = %entry, %for.body } define void @call_fill_range(i32* nocapture %p, i64* nocapture readonly %range) { -; ATTRIBUTOR-LABEL: define {{[^@]+}}@call_fill_range -; ATTRIBUTOR-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i64* nocapture nofree nonnull readonly align 8 dereferenceable(8) [[RANGE:%.*]]) -; ATTRIBUTOR-NEXT: entry: -; ATTRIBUTOR-NEXT: [[TMP0:%.*]] = load i64, i64* [[RANGE]], align 8, !range !0 -; ATTRIBUTOR-NEXT: tail call void @fill_range_inbounds(i32* nocapture nofree writeonly [[P]], i64 [[TMP0]]) -; ATTRIBUTOR-NEXT: tail call void @fill_range_not_inbounds(i32* nocapture nofree writeonly [[P]], i64 [[TMP0]]) -; ATTRIBUTOR-NEXT: ret void +; CHECK-LABEL: define {{[^@]+}}@call_fill_range +; CHECK-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i64* nocapture nofree nonnull readonly align 8 dereferenceable(8) [[RANGE:%.*]]) +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* [[RANGE]], align 8, !range !0 +; CHECK-NEXT: tail call void @fill_range_inbounds(i32* nocapture nofree writeonly [[P]], i64 [[TMP0]]) +; CHECK-NEXT: tail call void @fill_range_not_inbounds(i32* nocapture nofree writeonly [[P]], i64 [[TMP0]]) +; CHECK-NEXT: ret void ; entry: %0 = load i64, i64* %range, align 8, !range !0 @@ -312,6 +395,7 @@ declare void @use0() willreturn nounwind declare void @use1(i8*) willreturn nounwind declare void @use2(i8*, i8*) willreturn nounwind declare void @use3(i8*, i8*, i8*) willreturn nounwind + ; simple path test ; if(..) ; fun2(dereferenceable(8) %a, dereferenceable(8) %b) @@ -319,7 +403,17 @@ declare void @use3(i8*, i8*, i8*) willreturn nounwind ; fun2(dereferenceable(4) %a, %b) ; We can say that %a is dereferenceable(4) but %b is not. define void @simple-path(i8* %a, i8 * %b, i8 %c) { -; ATTRIBUTOR: define void @simple-path(i8* nonnull dereferenceable(4) %a, i8* %b, i8 %c) +; CHECK-LABEL: define {{[^@]+}}@simple-path +; CHECK-SAME: (i8* nonnull dereferenceable(4) [[A:%.*]], i8* [[B:%.*]], i8 [[C:%.*]]) +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[C]], 0 +; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] +; CHECK: if.then: +; CHECK-NEXT: tail call void @use2(i8* nonnull dereferenceable(8) [[A]], i8* nonnull dereferenceable(8) [[B]]) +; CHECK-NEXT: ret void +; CHECK: if.else: +; CHECK-NEXT: tail call void @use2(i8* nonnull dereferenceable(4) [[A]], i8* [[B]]) +; CHECK-NEXT: ret void +; %cmp = icmp eq i8 %c, 0 br i1 %cmp, label %if.then, label %if.else if.then: @@ -329,6 +423,7 @@ if.else: tail call void @use2(i8* dereferenceable(4) %a, i8* %b) ret void } + ; More complex test ; { ; fun1(dereferenceable(4) %a) @@ -341,9 +436,22 @@ if.else: ; fun1(dereferenceable(8) %a) ; } ; %a is dereferenceable(12) - define void @complex-path(i8* %a, i8* %b, i8 %c) { -; ATTRIBUTOR: define void @complex-path(i8* nonnull dereferenceable(12) %a, i8* nocapture nofree readnone %b, i8 %c) +; CHECK-LABEL: define {{[^@]+}}@complex-path +; CHECK-SAME: (i8* nonnull dereferenceable(12) [[A:%.*]], i8* nocapture nofree readnone [[B:%.*]], i8 [[C:%.*]]) +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[C]], 0 +; CHECK-NEXT: tail call void @use1(i8* nonnull dereferenceable(12) [[A]]) +; CHECK-NEXT: br i1 [[CMP]], label [[CONT_THEN:%.*]], label [[CONT_ELSE:%.*]] +; CHECK: cont.then: +; CHECK-NEXT: tail call void @use1(i8* nonnull dereferenceable(12) [[A]]) +; CHECK-NEXT: br label [[CONT2:%.*]] +; CHECK: cont.else: +; CHECK-NEXT: tail call void @use1(i8* nonnull dereferenceable(16) [[A]]) +; CHECK-NEXT: br label [[CONT2]] +; CHECK: cont2: +; CHECK-NEXT: tail call void @use1(i8* nonnull dereferenceable(12) [[A]]) +; CHECK-NEXT: ret void +; %cmp = icmp eq i8 %c, 0 tail call void @use1(i8* dereferenceable(4) %a) br i1 %cmp, label %cont.then, label %cont.else @@ -373,8 +481,33 @@ cont2: ; } ; ; FIXME: %ptr should be dereferenceable(4) -; ATTRIBUTOR: define dso_local void @rec-branch-1(i32 %a, i32 %b, i32 %c, i32* nocapture nofree writeonly %ptr) define dso_local void @rec-branch-1(i32 %a, i32 %b, i32 %c, i32* %ptr) { +; CHECK-LABEL: define {{[^@]+}}@rec-branch-1 +; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32* nocapture nofree writeonly [[PTR:%.*]]) +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[A]], 0 +; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_ELSE3:%.*]], label [[IF_THEN:%.*]] +; CHECK: if.then: +; CHECK-NEXT: [[TOBOOL1:%.*]] = icmp eq i32 [[B]], 0 +; CHECK-NEXT: br i1 [[TOBOOL1]], label [[IF_ELSE:%.*]], label [[IF_THEN2:%.*]] +; CHECK: if.then2: +; CHECK-NEXT: store i32 1, i32* [[PTR]], align 4 +; CHECK-NEXT: br label [[IF_END8:%.*]] +; CHECK: if.else: +; CHECK-NEXT: store i32 2, i32* [[PTR]], align 4 +; CHECK-NEXT: br label [[IF_END8]] +; CHECK: if.else3: +; CHECK-NEXT: [[TOBOOL4:%.*]] = icmp eq i32 [[C]], 0 +; CHECK-NEXT: br i1 [[TOBOOL4]], label [[IF_ELSE6:%.*]], label [[IF_THEN5:%.*]] +; CHECK: if.then5: +; CHECK-NEXT: store i32 3, i32* [[PTR]], align 4 +; CHECK-NEXT: br label [[IF_END8]] +; CHECK: if.else6: +; CHECK-NEXT: store i32 4, i32* [[PTR]], align 4 +; CHECK-NEXT: br label [[IF_END8]] +; CHECK: if.end8: +; CHECK-NEXT: ret void +; entry: %tobool = icmp eq i32 %a, 0 br i1 %tobool, label %if.else3, label %if.then @@ -421,8 +554,33 @@ if.end8: ; preds = %if.then5, %if.else6 ; } ; } ; FIXME: %ptr should be dereferenceable(4) -; ATTRIBUTOR: define dso_local void @rec-branch-2(i32 %a, i32 %b, i32 %c, i32* nocapture nofree writeonly %ptr) define dso_local void @rec-branch-2(i32 %a, i32 %b, i32 %c, i32* %ptr) { +; CHECK-LABEL: define {{[^@]+}}@rec-branch-2 +; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32* nocapture nofree writeonly [[PTR:%.*]]) +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[A]], 0 +; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_ELSE3:%.*]], label [[IF_THEN:%.*]] +; CHECK: if.then: +; CHECK-NEXT: [[TOBOOL1:%.*]] = icmp eq i32 [[B]], 0 +; CHECK-NEXT: br i1 [[TOBOOL1]], label [[IF_ELSE:%.*]], label [[IF_THEN2:%.*]] +; CHECK: if.then2: +; CHECK-NEXT: store i32 1, i32* [[PTR]], align 4 +; CHECK-NEXT: br label [[IF_END8:%.*]] +; CHECK: if.else: +; CHECK-NEXT: store i32 2, i32* [[PTR]], align 4 +; CHECK-NEXT: br label [[IF_END8]] +; CHECK: if.else3: +; CHECK-NEXT: [[TOBOOL4:%.*]] = icmp eq i32 [[C]], 0 +; CHECK-NEXT: br i1 [[TOBOOL4]], label [[IF_ELSE6:%.*]], label [[IF_THEN5:%.*]] +; CHECK: if.then5: +; CHECK-NEXT: store i32 3, i32* [[PTR]], align 4 +; CHECK-NEXT: br label [[IF_END8]] +; CHECK: if.else6: +; CHECK-NEXT: tail call void @rec-branch-2(i32 1, i32 1, i32 1, i32* nocapture nofree writeonly [[PTR]]) +; CHECK-NEXT: br label [[IF_END8]] +; CHECK: if.end8: +; CHECK-NEXT: ret void +; entry: %tobool = icmp eq i32 %a, 0 br i1 %tobool, label %if.else3, label %if.then @@ -462,6 +620,24 @@ define void @nonnull_assume_pos(i8* %arg1, i8* %arg2, i8* %arg3, i8* %arg4) { ; ATTRIBUTOR-NEXT: call void @llvm.assume(i1 true) #6 [ "nonnull"(i8* undef), "dereferenceable"(i8* undef, i64 1), "dereferenceable"(i8* undef, i64 2), "dereferenceable"(i8* undef, i64 101), "dereferenceable_or_null"(i8* undef, i64 31), "dereferenceable_or_null"(i8* undef, i64 42) ] ; ATTRIBUTOR-NEXT: call void @unknown() ; ATTRIBUTOR-NEXT: ret void +; +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@nonnull_assume_pos +; IS__TUNIT_OPM-SAME: (i8* nocapture nofree nonnull readnone dereferenceable(101) [[ARG1:%.*]], i8* nocapture nofree readnone dereferenceable_or_null(31) [[ARG2:%.*]], i8* nocapture nofree nonnull readnone [[ARG3:%.*]], i8* nocapture nofree readnone dereferenceable_or_null(42) [[ARG4:%.*]]) +; IS__TUNIT_OPM-NEXT: call void @llvm.assume(i1 true) #6 [ "nonnull"(i8* undef), "dereferenceable"(i8* undef, i64 1), "dereferenceable"(i8* undef, i64 2), "dereferenceable"(i8* undef, i64 101), "dereferenceable_or_null"(i8* undef, i64 31), "dereferenceable_or_null"(i8* undef, i64 42) ] +; IS__TUNIT_OPM-NEXT: call void @unknown() +; IS__TUNIT_OPM-NEXT: ret void +; +; IS________NPM-LABEL: define {{[^@]+}}@nonnull_assume_pos +; IS________NPM-SAME: (i8* nocapture nofree nonnull readnone dereferenceable(101) [[ARG1:%.*]], i8* nocapture nofree readnone dereferenceable_or_null(31) [[ARG2:%.*]], i8* nocapture nofree nonnull readnone [[ARG3:%.*]], i8* nocapture nofree readnone dereferenceable_or_null(42) [[ARG4:%.*]]) +; IS________NPM-NEXT: call void @llvm.assume(i1 true) #7 [ "nonnull"(i8* undef), "dereferenceable"(i8* undef, i64 1), "dereferenceable"(i8* undef, i64 2), "dereferenceable"(i8* undef, i64 101), "dereferenceable_or_null"(i8* undef, i64 31), "dereferenceable_or_null"(i8* undef, i64 42) ] +; IS________NPM-NEXT: call void @unknown() +; IS________NPM-NEXT: ret void +; +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@nonnull_assume_pos +; IS__CGSCC_OPM-SAME: (i8* nocapture nofree nonnull readnone dereferenceable(101) [[ARG1:%.*]], i8* nocapture nofree readnone dereferenceable_or_null(31) [[ARG2:%.*]], i8* nocapture nofree nonnull readnone [[ARG3:%.*]], i8* nocapture nofree readnone dereferenceable_or_null(42) [[ARG4:%.*]]) +; IS__CGSCC_OPM-NEXT: call void @llvm.assume(i1 true) #8 [ "nonnull"(i8* undef), "dereferenceable"(i8* undef, i64 1), "dereferenceable"(i8* undef, i64 2), "dereferenceable"(i8* undef, i64 101), "dereferenceable_or_null"(i8* undef, i64 31), "dereferenceable_or_null"(i8* undef, i64 42) ] +; IS__CGSCC_OPM-NEXT: call void @unknown() +; IS__CGSCC_OPM-NEXT: ret void ; call void @llvm.assume(i1 true) [ "nonnull"(i8* %arg3), "dereferenceable"(i8* %arg1, i64 1), "dereferenceable"(i8* %arg1, i64 2), "dereferenceable"(i8* %arg1, i64 101), "dereferenceable_or_null"(i8* %arg2, i64 31), "dereferenceable_or_null"(i8* %arg4, i64 42)] call void @unknown() @@ -473,6 +649,12 @@ define void @nonnull_assume_neg(i8* %arg1, i8* %arg2, i8* %arg3) { ; ATTRIBUTOR-NEXT: call void @unknown() ; ATTRIBUTOR-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i8* undef, i64 101), "dereferenceable"(i8* undef, i64 -2), "dereferenceable_or_null"(i8* undef, i64 31) ] ; ATTRIBUTOR-NEXT: ret void +; +; CHECK-LABEL: define {{[^@]+}}@nonnull_assume_neg +; CHECK-SAME: (i8* nocapture nofree readnone [[ARG1:%.*]], i8* nocapture nofree readnone [[ARG2:%.*]], i8* nocapture nofree readnone [[ARG3:%.*]]) +; CHECK-NEXT: call void @unknown() +; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i8* undef, i64 101), "dereferenceable"(i8* undef, i64 -2), "dereferenceable_or_null"(i8* undef, i64 31) ] +; CHECK-NEXT: ret void ; call void @unknown() call void @llvm.assume(i1 true) ["dereferenceable"(i8* %arg1, i64 101), "dereferenceable"(i8* %arg2, i64 -2), "dereferenceable_or_null"(i8* %arg3, i64 31)] @@ -496,6 +678,24 @@ define void @nonnull_assume_call(i8* %arg1, i8* %arg2, i8* %arg3, i8* %arg4) { ; ATTRIBUTOR-NEXT: call void @unknown_use32(i32* nonnull dereferenceable(101) [[P]]) ; ATTRIBUTOR-NEXT: call void @unknown() ; ATTRIBUTOR-NEXT: ret void +; +; CHECK-LABEL: define {{[^@]+}}@nonnull_assume_call +; CHECK-SAME: (i8* [[ARG1:%.*]], i8* [[ARG2:%.*]], i8* [[ARG3:%.*]], i8* [[ARG4:%.*]]) +; CHECK-NEXT: call void @unknown() +; CHECK-NEXT: [[P:%.*]] = call nonnull dereferenceable(101) i32* @unkown_ptr() +; CHECK-NEXT: call void @unknown_use32(i32* nonnull dereferenceable(101) [[P]]) +; CHECK-NEXT: call void @unknown_use8(i8* nonnull dereferenceable(42) [[ARG4]]) +; CHECK-NEXT: call void @unknown_use8(i8* nonnull [[ARG3]]) +; CHECK-NEXT: call void @unknown_use8(i8* nonnull dereferenceable(31) [[ARG2]]) +; CHECK-NEXT: call void @unknown_use8(i8* nonnull dereferenceable(2) [[ARG1]]) +; CHECK-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(i8* [[ARG3]]), "dereferenceable"(i8* [[ARG1]], i64 1), "dereferenceable"(i8* [[ARG1]], i64 2), "dereferenceable"(i32* [[P]], i64 101), "dereferenceable_or_null"(i8* [[ARG2]], i64 31), "dereferenceable_or_null"(i8* [[ARG4]], i64 42) ] +; CHECK-NEXT: call void @unknown_use8(i8* nonnull dereferenceable(2) [[ARG1]]) +; CHECK-NEXT: call void @unknown_use8(i8* nonnull dereferenceable(31) [[ARG2]]) +; CHECK-NEXT: call void @unknown_use8(i8* nonnull [[ARG3]]) +; CHECK-NEXT: call void @unknown_use8(i8* nonnull dereferenceable(42) [[ARG4]]) +; CHECK-NEXT: call void @unknown_use32(i32* nonnull dereferenceable(101) [[P]]) +; CHECK-NEXT: call void @unknown() +; CHECK-NEXT: ret void ; call void @unknown() %p = call i32* @unkown_ptr() diff --git a/llvm/test/Transforms/Attributor/dereferenceable-2.ll b/llvm/test/Transforms/Attributor/dereferenceable-2.ll index 7ffc837caadc..3e94364a816b 100644 --- a/llvm/test/Transforms/Attributor/dereferenceable-2.ll +++ b/llvm/test/Transforms/Attributor/dereferenceable-2.ll @@ -1,12 +1,29 @@ -; RUN: opt < %s -attributor --attributor-disable=false -S | FileCheck %s --check-prefix=ATTRIBUTOR -; RUN: opt < %s -passes=attributor --attributor-disable=false -S | FileCheck %s --check-prefix=ATTRIBUTOR_CGSCC_NPM -; Copied from Transforms/InferFunctionAttrs/dereferenceable.ll +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 ; Determine dereference-ability before unused loads get deleted: ; https://bugs.llvm.org/show_bug.cgi?id=21780 define <4 x double> @PR21780(double* %ptr) { -; ATTRIBUTOR-LABEL: @PR21780(double* nocapture nofree nonnull readonly align 8 dereferenceable(32) %ptr) +; CHECK-LABEL: define {{[^@]+}}@PR21780 +; CHECK-SAME: (double* nocapture nofree nonnull readonly align 8 dereferenceable(32) [[PTR:%.*]]) +; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds double, double* [[PTR]], i64 1 +; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds double, double* [[PTR]], i64 2 +; CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds double, double* [[PTR]], i64 3 +; CHECK-NEXT: [[T0:%.*]] = load double, double* [[PTR]], align 8 +; CHECK-NEXT: [[T1:%.*]] = load double, double* [[ARRAYIDX1]], align 8 +; CHECK-NEXT: [[T2:%.*]] = load double, double* [[ARRAYIDX2]], align 8 +; CHECK-NEXT: [[T3:%.*]] = load double, double* [[ARRAYIDX3]], align 8 +; CHECK-NEXT: [[VECINIT0:%.*]] = insertelement <4 x double> undef, double [[T0]], i32 0 +; CHECK-NEXT: [[VECINIT1:%.*]] = insertelement <4 x double> [[VECINIT0]], double [[T1]], i32 1 +; CHECK-NEXT: [[VECINIT2:%.*]] = insertelement <4 x double> [[VECINIT1]], double [[T2]], i32 2 +; CHECK-NEXT: [[VECINIT3:%.*]] = insertelement <4 x double> [[VECINIT2]], double [[T3]], i32 3 +; CHECK-NEXT: [[SHUFFLE:%.*]] = shufflevector <4 x double> [[VECINIT3]], <4 x double> [[VECINIT3]], <4 x i32> +; CHECK-NEXT: ret <4 x double> [[SHUFFLE]] +; ; GEP of index 0 is simplified away. %arrayidx1 = getelementptr inbounds double, double* %ptr, i64 1 @@ -28,7 +45,12 @@ define <4 x double> @PR21780(double* %ptr) { define double @PR21780_only_access3_with_inbounds(double* %ptr) { -; ATTRIBUTOR-LABEL: @PR21780_only_access3_with_inbounds(double* nocapture nofree nonnull readonly align 8 dereferenceable(32) %ptr) +; CHECK-LABEL: define {{[^@]+}}@PR21780_only_access3_with_inbounds +; CHECK-SAME: (double* nocapture nofree nonnull readonly align 8 dereferenceable(32) [[PTR:%.*]]) +; CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds double, double* [[PTR]], i64 3 +; CHECK-NEXT: [[T3:%.*]] = load double, double* [[ARRAYIDX3]], align 8 +; CHECK-NEXT: ret double [[T3]] +; %arrayidx3 = getelementptr inbounds double, double* %ptr, i64 3 %t3 = load double, double* %arrayidx3, align 8 @@ -36,14 +58,24 @@ define double @PR21780_only_access3_with_inbounds(double* %ptr) { } define double @PR21780_only_access3_without_inbounds(double* %ptr) { -; ATTRIBUTOR-LABEL: @PR21780_only_access3_without_inbounds(double* nocapture nofree readonly align 8 %ptr) +; CHECK-LABEL: define {{[^@]+}}@PR21780_only_access3_without_inbounds +; CHECK-SAME: (double* nocapture nofree readonly align 8 [[PTR:%.*]]) +; CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr double, double* [[PTR]], i64 3 +; CHECK-NEXT: [[T3:%.*]] = load double, double* [[ARRAYIDX3]], align 8 +; CHECK-NEXT: ret double [[T3]] +; %arrayidx3 = getelementptr double, double* %ptr, i64 3 %t3 = load double, double* %arrayidx3, align 8 ret double %t3 } define double @PR21780_without_inbounds(double* %ptr) { -; ATTRIBUTOR-LABEL: @PR21780_without_inbounds(double* nocapture nofree nonnull readonly align 8 dereferenceable(32) %ptr) +; CHECK-LABEL: define {{[^@]+}}@PR21780_without_inbounds +; CHECK-SAME: (double* nocapture nofree nonnull readonly align 8 dereferenceable(32) [[PTR:%.*]]) +; CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr double, double* [[PTR]], i64 3 +; CHECK-NEXT: [[T3:%.*]] = load double, double* [[ARRAYIDX3]], align 8 +; CHECK-NEXT: ret double [[T3]] +; %arrayidx1 = getelementptr double, double* %ptr, i64 1 %arrayidx2 = getelementptr double, double* %ptr, i64 2 @@ -60,7 +92,13 @@ define double @PR21780_without_inbounds(double* %ptr) { ; Unsimplified, but still valid. Also, throw in some bogus arguments. define void @gep0(i8* %unused, i8* %other, i8* %ptr) { -; ATTRIBUTOR-LABEL: @gep0(i8* nocapture nofree readnone %unused, i8* nocapture nofree nonnull writeonly dereferenceable(1) %other, i8* nocapture nofree nonnull readonly dereferenceable(3) %ptr) +; CHECK-LABEL: define {{[^@]+}}@gep0 +; CHECK-SAME: (i8* nocapture nofree readnone [[UNUSED:%.*]], i8* nocapture nofree nonnull writeonly dereferenceable(1) [[OTHER:%.*]], i8* nocapture nofree nonnull readonly dereferenceable(3) [[PTR:%.*]]) +; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr i8, i8* [[PTR]], i64 2 +; CHECK-NEXT: [[T2:%.*]] = load i8, i8* [[ARRAYIDX2]] +; CHECK-NEXT: store i8 [[T2]], i8* [[OTHER]] +; CHECK-NEXT: ret void +; %arrayidx0 = getelementptr i8, i8* %ptr, i64 0 %arrayidx1 = getelementptr i8, i8* %ptr, i64 1 %arrayidx2 = getelementptr i8, i8* %ptr, i64 2 @@ -75,7 +113,10 @@ define void @gep0(i8* %unused, i8* %other, i8* %ptr) { ; Multiple arguments may be dereferenceable. define void @ordering(i8* %ptr1, i32* %ptr2) { -; ATTRIBUTOR-LABEL: @ordering(i8* nocapture nofree nonnull readnone dereferenceable(3) %ptr1, i32* nocapture nofree nonnull readnone align 4 dereferenceable(8) %ptr2) +; CHECK-LABEL: define {{[^@]+}}@ordering +; CHECK-SAME: (i8* nocapture nofree nonnull readnone dereferenceable(3) [[PTR1:%.*]], i32* nocapture nofree nonnull readnone align 4 dereferenceable(8) [[PTR2:%.*]]) +; CHECK-NEXT: ret void +; %a20 = getelementptr i32, i32* %ptr2, i64 0 %a12 = getelementptr i8, i8* %ptr1, i64 2 %t12 = load i8, i8* %a12 @@ -92,7 +133,13 @@ define void @ordering(i8* %ptr1, i32* %ptr2) { ; Not in entry block. define void @not_entry_but_guaranteed_to_execute(i8* %ptr) { -; ATTRIBUTOR-LABEL: @not_entry_but_guaranteed_to_execute(i8* nocapture nofree nonnull readnone dereferenceable(3) %ptr) +; CHECK-LABEL: define {{[^@]+}}@not_entry_but_guaranteed_to_execute +; CHECK-SAME: (i8* nocapture nofree nonnull readnone dereferenceable(3) [[PTR:%.*]]) +; CHECK-NEXT: entry: +; CHECK-NEXT: br label [[EXIT:%.*]] +; CHECK: exit: +; CHECK-NEXT: ret void +; entry: br label %exit exit: @@ -108,7 +155,15 @@ exit: ; Not in entry block and not guaranteed to execute. define void @not_entry_not_guaranteed_to_execute(i8* %ptr, i1 %cond) { -; ATTRIBUTOR-LABEL: @not_entry_not_guaranteed_to_execute(i8* nocapture nofree readnone %ptr, i1 %cond) +; CHECK-LABEL: define {{[^@]+}}@not_entry_not_guaranteed_to_execute +; CHECK-SAME: (i8* nocapture nofree readnone [[PTR:%.*]], i1 [[COND:%.*]]) +; CHECK-NEXT: entry: +; CHECK-NEXT: br i1 [[COND]], label [[LOADS:%.*]], label [[EXIT:%.*]] +; CHECK: loads: +; CHECK-NEXT: ret void +; CHECK: exit: +; CHECK-NEXT: ret void +; entry: br i1 %cond, label %loads, label %exit loads: @@ -126,7 +181,15 @@ exit: ; The last load may not execute, so derefenceable bytes only covers the 1st two loads. define void @partial_in_entry(i16* %ptr, i1 %cond) { -; ATTRIBUTOR-LABEL: @partial_in_entry(i16* nocapture nofree nonnull readnone align 2 dereferenceable(4) %ptr, i1 %cond) +; CHECK-LABEL: define {{[^@]+}}@partial_in_entry +; CHECK-SAME: (i16* nocapture nofree nonnull readnone align 2 dereferenceable(4) [[PTR:%.*]], i1 [[COND:%.*]]) +; CHECK-NEXT: entry: +; CHECK-NEXT: br i1 [[COND]], label [[LOADS:%.*]], label [[EXIT:%.*]] +; CHECK: loads: +; CHECK-NEXT: ret void +; CHECK: exit: +; CHECK-NEXT: ret void +; entry: %arrayidx0 = getelementptr i16, i16* %ptr, i64 0 %arrayidx1 = getelementptr i16, i16* %ptr, i64 1 @@ -145,7 +208,12 @@ exit: ; The 2nd and 3rd loads may never execute. define void @volatile_is_not_dereferenceable(i16* %ptr) { -; ATTRIBUTOR-LABEL: @volatile_is_not_dereferenceable(i16* nofree align 2 %ptr) +; CHECK-LABEL: define {{[^@]+}}@volatile_is_not_dereferenceable +; CHECK-SAME: (i16* nofree align 2 [[PTR:%.*]]) +; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i16, i16* [[PTR]], i64 0 +; CHECK-NEXT: [[T0:%.*]] = load volatile i16, i16* [[ARRAYIDX0]], align 2 +; CHECK-NEXT: ret void +; %arrayidx0 = getelementptr i16, i16* %ptr, i64 0 %arrayidx1 = getelementptr i16, i16* %ptr, i64 1 %arrayidx2 = getelementptr i16, i16* %ptr, i64 2 @@ -158,7 +226,10 @@ define void @volatile_is_not_dereferenceable(i16* %ptr) { ; TODO: We should allow inference for atomic (but not volatile) ops. define void @atomic_is_alright(i16* %ptr) { -; ATTRIBUTOR-LABEL: @atomic_is_alright(i16* nocapture nofree nonnull readnone align 2 dereferenceable(6) %ptr) +; CHECK-LABEL: define {{[^@]+}}@atomic_is_alright +; CHECK-SAME: (i16* nocapture nofree nonnull readnone align 2 dereferenceable(6) [[PTR:%.*]]) +; CHECK-NEXT: ret void +; %arrayidx0 = getelementptr i16, i16* %ptr, i64 0 %arrayidx1 = getelementptr i16, i16* %ptr, i64 1 %arrayidx2 = getelementptr i16, i16* %ptr, i64 2 @@ -171,7 +242,11 @@ define void @atomic_is_alright(i16* %ptr) { declare void @may_not_return() define void @not_guaranteed_to_transfer_execution(i16* %ptr) { -; ATTRIBUTOR-LABEL: @not_guaranteed_to_transfer_execution(i16* nocapture nofree nonnull readnone align 2 dereferenceable(2) %ptr) +; CHECK-LABEL: define {{[^@]+}}@not_guaranteed_to_transfer_execution +; CHECK-SAME: (i16* nocapture nofree nonnull readnone align 2 dereferenceable(2) [[PTR:%.*]]) +; CHECK-NEXT: call void @may_not_return() +; CHECK-NEXT: ret void +; %arrayidx0 = getelementptr i16, i16* %ptr, i64 0 %arrayidx1 = getelementptr i16, i16* %ptr, i64 1 %arrayidx2 = getelementptr i16, i16* %ptr, i64 2 @@ -185,7 +260,10 @@ define void @not_guaranteed_to_transfer_execution(i16* %ptr) { ; We must have consecutive accesses. define void @variable_gep_index(i8* %unused, i8* %ptr, i64 %variable_index) { -; ATTRIBUTOR-LABEL: @variable_gep_index(i8* nocapture nofree readnone %unused, i8* nocapture nofree nonnull readnone dereferenceable(1) %ptr, i64 %variable_index) +; CHECK-LABEL: define {{[^@]+}}@variable_gep_index +; CHECK-SAME: (i8* nocapture nofree readnone [[UNUSED:%.*]], i8* nocapture nofree nonnull readnone dereferenceable(1) [[PTR:%.*]], i64 [[VARIABLE_INDEX:%.*]]) +; CHECK-NEXT: ret void +; %arrayidx1 = getelementptr i8, i8* %ptr, i64 %variable_index %arrayidx2 = getelementptr i8, i8* %ptr, i64 2 %t0 = load i8, i8* %ptr @@ -198,7 +276,10 @@ define void @variable_gep_index(i8* %unused, i8* %ptr, i64 %variable_index) { define void @multi_index_gep(<4 x i8>* %ptr) { ; FIXME: %ptr should be dereferenceable(4) -; ATTRIBUTOR-LABEL: @multi_index_gep(<4 x i8>* nocapture nofree nonnull readnone dereferenceable(1) %ptr) +; CHECK-LABEL: define {{[^@]+}}@multi_index_gep +; CHECK-SAME: (<4 x i8>* nocapture nofree nonnull readnone dereferenceable(1) [[PTR:%.*]]) +; CHECK-NEXT: ret void +; %arrayidx00 = getelementptr <4 x i8>, <4 x i8>* %ptr, i64 0, i64 0 %t0 = load i8, i8* %arrayidx00 ret void @@ -207,7 +288,10 @@ define void @multi_index_gep(<4 x i8>* %ptr) { ; Could round weird bitwidths down? define void @not_byte_multiple(i9* %ptr) { -; ATTRIBUTOR-LABEL: @not_byte_multiple(i9* nocapture nofree nonnull readnone align 2 dereferenceable(2) %ptr) +; CHECK-LABEL: define {{[^@]+}}@not_byte_multiple +; CHECK-SAME: (i9* nocapture nofree nonnull readnone align 2 dereferenceable(2) [[PTR:%.*]]) +; CHECK-NEXT: ret void +; %arrayidx0 = getelementptr i9, i9* %ptr, i64 0 %t0 = load i9, i9* %arrayidx0 ret void @@ -216,7 +300,10 @@ define void @not_byte_multiple(i9* %ptr) { ; Missing direct access from the pointer. define void @no_pointer_deref(i16* %ptr) { -; ATTRIBUTOR-LABEL: @no_pointer_deref(i16* nocapture nofree readnone align 2 %ptr) +; CHECK-LABEL: define {{[^@]+}}@no_pointer_deref +; CHECK-SAME: (i16* nocapture nofree readnone align 2 [[PTR:%.*]]) +; CHECK-NEXT: ret void +; %arrayidx1 = getelementptr i16, i16* %ptr, i64 1 %arrayidx2 = getelementptr i16, i16* %ptr, i64 2 %t1 = load i16, i16* %arrayidx1 @@ -227,7 +314,10 @@ define void @no_pointer_deref(i16* %ptr) { ; Out-of-order is ok, but missing access concludes dereferenceable range. define void @non_consecutive(i32* %ptr) { -; ATTRIBUTOR-LABEL: @non_consecutive(i32* nocapture nofree nonnull readnone align 4 dereferenceable(8) %ptr) +; CHECK-LABEL: define {{[^@]+}}@non_consecutive +; CHECK-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(8) [[PTR:%.*]]) +; CHECK-NEXT: ret void +; %arrayidx1 = getelementptr i32, i32* %ptr, i64 1 %arrayidx0 = getelementptr i32, i32* %ptr, i64 0 %arrayidx3 = getelementptr i32, i32* %ptr, i64 3 @@ -240,7 +330,10 @@ define void @non_consecutive(i32* %ptr) { ; Improve on existing dereferenceable attribute. define void @more_bytes(i32* dereferenceable(8) %ptr) { -; ATTRIBUTOR-LABEL: @more_bytes(i32* nocapture nofree nonnull readnone align 4 dereferenceable(16) %ptr) +; CHECK-LABEL: define {{[^@]+}}@more_bytes +; CHECK-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(16) [[PTR:%.*]]) +; CHECK-NEXT: ret void +; %arrayidx3 = getelementptr i32, i32* %ptr, i64 3 %arrayidx1 = getelementptr i32, i32* %ptr, i64 1 %arrayidx0 = getelementptr i32, i32* %ptr, i64 0 @@ -255,7 +348,10 @@ define void @more_bytes(i32* dereferenceable(8) %ptr) { ; Improve on existing dereferenceable_or_null attribute. define void @more_bytes_and_not_null(i32* dereferenceable_or_null(8) %ptr) { -; ATTRIBUTOR-LABEL: @more_bytes_and_not_null(i32* nocapture nofree nonnull readnone align 4 dereferenceable(16) %ptr) +; CHECK-LABEL: define {{[^@]+}}@more_bytes_and_not_null +; CHECK-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(16) [[PTR:%.*]]) +; CHECK-NEXT: ret void +; %arrayidx3 = getelementptr i32, i32* %ptr, i64 3 %arrayidx1 = getelementptr i32, i32* %ptr, i64 1 %arrayidx0 = getelementptr i32, i32* %ptr, i64 0 @@ -270,7 +366,10 @@ define void @more_bytes_and_not_null(i32* dereferenceable_or_null(8) %ptr) { ; But don't pessimize existing dereferenceable attribute. define void @better_bytes(i32* dereferenceable(100) %ptr) { -; ATTRIBUTOR-LABEL: @better_bytes(i32* nocapture nofree nonnull readnone align 4 dereferenceable(100) %ptr) +; CHECK-LABEL: define {{[^@]+}}@better_bytes +; CHECK-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(100) [[PTR:%.*]]) +; CHECK-NEXT: ret void +; %arrayidx3 = getelementptr i32, i32* %ptr, i64 3 %arrayidx1 = getelementptr i32, i32* %ptr, i64 1 %arrayidx0 = getelementptr i32, i32* %ptr, i64 0 @@ -283,7 +382,10 @@ define void @better_bytes(i32* dereferenceable(100) %ptr) { } define void @bitcast(i32* %arg) { -; ATTRIBUTOR-LABEL: @bitcast(i32* nocapture nofree nonnull readnone align 4 dereferenceable(8) %arg) +; CHECK-LABEL: define {{[^@]+}}@bitcast +; CHECK-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(8) [[ARG:%.*]]) +; CHECK-NEXT: ret void +; %ptr = bitcast i32* %arg to float* %arrayidx0 = getelementptr float, float* %ptr, i64 0 %arrayidx1 = getelementptr float, float* %ptr, i64 1 @@ -293,7 +395,10 @@ define void @bitcast(i32* %arg) { } define void @bitcast_different_sizes(double* %arg1, i8* %arg2) { -; ATTRIBUTOR-LABEL: @bitcast_different_sizes(double* nocapture nofree nonnull readnone align 4 dereferenceable(12) %arg1, i8* nocapture nofree nonnull readnone align 4 dereferenceable(16) %arg2) +; CHECK-LABEL: define {{[^@]+}}@bitcast_different_sizes +; CHECK-SAME: (double* nocapture nofree nonnull readnone align 4 dereferenceable(12) [[ARG1:%.*]], i8* nocapture nofree nonnull readnone align 4 dereferenceable(16) [[ARG2:%.*]]) +; CHECK-NEXT: ret void +; %ptr1 = bitcast double* %arg1 to float* %a10 = getelementptr float, float* %ptr1, i64 0 %a11 = getelementptr float, float* %ptr1, i64 1 @@ -311,7 +416,10 @@ define void @bitcast_different_sizes(double* %arg1, i8* %arg2) { } define void @negative_offset(i32* %arg) { -; ATTRIBUTOR-LABEL: @negative_offset(i32* nocapture nofree nonnull readnone align 4 dereferenceable(4) %arg) +; CHECK-LABEL: define {{[^@]+}}@negative_offset +; CHECK-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(4) [[ARG:%.*]]) +; CHECK-NEXT: ret void +; %ptr = bitcast i32* %arg to float* %arrayidx0 = getelementptr float, float* %ptr, i64 0 %arrayidx1 = getelementptr float, float* %ptr, i64 -1 @@ -321,7 +429,15 @@ define void @negative_offset(i32* %arg) { } define void @stores(i32* %arg) { -; ATTRIBUTOR-LABEL: @stores(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(8) %arg) +; CHECK-LABEL: define {{[^@]+}}@stores +; CHECK-SAME: (i32* nocapture nofree nonnull writeonly align 4 dereferenceable(8) [[ARG:%.*]]) +; CHECK-NEXT: [[PTR:%.*]] = bitcast i32* [[ARG]] to float* +; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr float, float* [[PTR]], i64 0 +; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr float, float* [[PTR]], i64 1 +; CHECK-NEXT: store float 1.000000e+00, float* [[ARRAYIDX0]], align 4 +; CHECK-NEXT: store float 2.000000e+00, float* [[ARRAYIDX1]], align 4 +; CHECK-NEXT: ret void +; %ptr = bitcast i32* %arg to float* %arrayidx0 = getelementptr float, float* %ptr, i64 0 %arrayidx1 = getelementptr float, float* %ptr, i64 1 @@ -331,7 +447,13 @@ define void @stores(i32* %arg) { } define void @load_store(i32* %arg) { -; ATTRIBUTOR-LABEL: @load_store(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(8) %arg) +; CHECK-LABEL: define {{[^@]+}}@load_store +; CHECK-SAME: (i32* nocapture nofree nonnull writeonly align 4 dereferenceable(8) [[ARG:%.*]]) +; CHECK-NEXT: [[PTR:%.*]] = bitcast i32* [[ARG]] to float* +; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr float, float* [[PTR]], i64 1 +; CHECK-NEXT: store float 2.000000e+00, float* [[ARRAYIDX1]], align 4 +; CHECK-NEXT: ret void +; %ptr = bitcast i32* %arg to float* %arrayidx0 = getelementptr float, float* %ptr, i64 0 %arrayidx1 = getelementptr float, float* %ptr, i64 1 @@ -341,7 +463,13 @@ define void @load_store(i32* %arg) { } define void @different_size1(i32* %arg) { -; ATTRIBUTOR-LABEL: @different_size1(i32* nocapture nofree nonnull writeonly align 8 dereferenceable(8) %arg) +; CHECK-LABEL: define {{[^@]+}}@different_size1 +; CHECK-SAME: (i32* nocapture nofree nonnull writeonly align 8 dereferenceable(8) [[ARG:%.*]]) +; CHECK-NEXT: [[ARG_CAST:%.*]] = bitcast i32* [[ARG]] to double* +; CHECK-NEXT: store double 0.000000e+00, double* [[ARG_CAST]], align 8 +; CHECK-NEXT: store i32 0, i32* [[ARG]], align 8 +; CHECK-NEXT: ret void +; %arg-cast = bitcast i32* %arg to double* store double 0.000000e+00, double* %arg-cast store i32 0, i32* %arg @@ -349,7 +477,13 @@ define void @different_size1(i32* %arg) { } define void @different_size2(i32* %arg) { -; ATTRIBUTOR-LABEL: @different_size2(i32* nocapture nofree nonnull writeonly align 8 dereferenceable(8) %arg) +; CHECK-LABEL: define {{[^@]+}}@different_size2 +; CHECK-SAME: (i32* nocapture nofree nonnull writeonly align 8 dereferenceable(8) [[ARG:%.*]]) +; CHECK-NEXT: store i32 0, i32* [[ARG]], align 8 +; CHECK-NEXT: [[ARG_CAST:%.*]] = bitcast i32* [[ARG]] to double* +; CHECK-NEXT: store double 0.000000e+00, double* [[ARG_CAST]], align 8 +; CHECK-NEXT: ret void +; store i32 0, i32* %arg %arg-cast = bitcast i32* %arg to double* store double 0.000000e+00, double* %arg-cast @@ -375,12 +509,63 @@ define void @different_size2(i32* %arg) { ; ; ATTRIBUTOR_CGSCC_NPM-LABEL: define i32 @require_cfg_analysis(i32 %c, i32* {{.*}} dereferenceable(4) %p) define i32 @require_cfg_analysis(i32 %c, i32* %p) { +; IS________OPM-LABEL: define {{[^@]+}}@require_cfg_analysis +; IS________OPM-SAME: (i32 [[C:%.*]], i32* nocapture nofree writeonly [[P:%.*]]) +; IS________OPM-NEXT: [[TOBOOL1:%.*]] = icmp eq i32 [[C]], 0 +; IS________OPM-NEXT: br i1 [[TOBOOL1]], label [[L1:%.*]], label [[L2:%.*]] +; IS________OPM: l1: +; IS________OPM-NEXT: [[TOBOOL2:%.*]] = icmp eq i32 [[C]], 1 +; IS________OPM-NEXT: br i1 [[TOBOOL2]], label [[L3:%.*]], label [[L4:%.*]] +; IS________OPM: l2: +; IS________OPM-NEXT: [[TOBOOL3:%.*]] = icmp eq i32 [[C]], 2 +; IS________OPM-NEXT: br i1 [[TOBOOL3]], label [[L3]], label [[L4]] +; IS________OPM: l3: +; IS________OPM-NEXT: br label [[L5:%.*]] +; IS________OPM: l4: +; IS________OPM-NEXT: br label [[L5]] +; IS________OPM: l5: +; IS________OPM-NEXT: [[TOBOOL4:%.*]] = icmp eq i32 [[C]], 4 +; IS________OPM-NEXT: br i1 [[TOBOOL4]], label [[L6:%.*]], label [[L7:%.*]] +; IS________OPM: l6: +; IS________OPM-NEXT: store i32 0, i32* [[P]] +; IS________OPM-NEXT: br label [[END:%.*]] +; IS________OPM: l7: +; IS________OPM-NEXT: store i32 1, i32* [[P]] +; IS________OPM-NEXT: br label [[END]] +; IS________OPM: end: +; IS________OPM-NEXT: ret i32 1 +; +; IS________NPM-LABEL: define {{[^@]+}}@require_cfg_analysis +; IS________NPM-SAME: (i32 [[C:%.*]], i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[P:%.*]]) +; IS________NPM-NEXT: [[TOBOOL1:%.*]] = icmp eq i32 [[C]], 0 +; IS________NPM-NEXT: br i1 [[TOBOOL1]], label [[L1:%.*]], label [[L2:%.*]] +; IS________NPM: l1: +; IS________NPM-NEXT: br label [[L4:%.*]] +; IS________NPM: l2: +; IS________NPM-NEXT: [[TOBOOL3:%.*]] = icmp eq i32 [[C]], 2 +; IS________NPM-NEXT: br i1 [[TOBOOL3]], label [[L3:%.*]], label [[L4]] +; IS________NPM: l3: +; IS________NPM-NEXT: br label [[L5:%.*]] +; IS________NPM: l4: +; IS________NPM-NEXT: br label [[L5]] +; IS________NPM: l5: +; IS________NPM-NEXT: [[TOBOOL4:%.*]] = icmp eq i32 [[C]], 4 +; IS________NPM-NEXT: br i1 [[TOBOOL4]], label [[L6:%.*]], label [[L7:%.*]] +; IS________NPM: l6: +; IS________NPM-NEXT: store i32 0, i32* [[P]], align 4 +; IS________NPM-NEXT: br label [[END:%.*]] +; IS________NPM: l7: +; IS________NPM-NEXT: store i32 1, i32* [[P]], align 4 +; IS________NPM-NEXT: br label [[END]] +; IS________NPM: end: +; IS________NPM-NEXT: ret i32 1 +; %tobool1 = icmp eq i32 %c, 0 br i1 %tobool1, label %l1, label %l2 -l1: +l1: %tobool2 = icmp eq i32 %c, 1 br i1 %tobool2, label %l3, label %l4 -l2: +l2: %tobool3 = icmp eq i32 %c, 2 br i1 %tobool3, label %l3, label %l4 l3: diff --git a/llvm/test/Transforms/Attributor/heap_to_stack.ll b/llvm/test/Transforms/Attributor/heap_to_stack.ll index 3adbf3812f17..3049d5154100 100644 --- a/llvm/test/Transforms/Attributor/heap_to_stack.ll +++ b/llvm/test/Transforms/Attributor/heap_to_stack.ll @@ -1,4 +1,8 @@ -; RUN: opt -passes=attributor --attributor-disable=false -attributor-annotate-decl-cs -S < %s | FileCheck %s +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 declare noalias i8* @malloc(i64) @@ -24,8 +28,13 @@ declare void @free(i8* nocapture) declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) nounwind -; CHECK: @nofree_arg_only(i8* nocapture nofree %p1, i8* nocapture %p2) define void @nofree_arg_only(i8* %p1, i8* %p2) { +; CHECK-LABEL: define {{[^@]+}}@nofree_arg_only +; CHECK-SAME: (i8* nocapture nofree [[P1:%.*]], i8* nocapture [[P2:%.*]]) +; CHECK-NEXT: tail call void @free(i8* nocapture [[P2]]) +; CHECK-NEXT: tail call void @nofree_func(i8* nocapture nofree [[P1]]) +; CHECK-NEXT: ret void +; tail call void @free(i8* %p2) tail call void @nofree_func(i8* %p1) ret void @@ -34,9 +43,21 @@ define void @nofree_arg_only(i8* %p1, i8* %p2) { ; TEST 1 - negative, pointer freed in another function. define void @test1() { +; IS________OPM-LABEL: define {{[^@]+}}@test1() +; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 4) +; IS________OPM-NEXT: tail call void @nocapture_func_frees_pointer(i8* noalias [[TMP1]]) +; IS________OPM-NEXT: tail call void (...) @func_throws() +; IS________OPM-NEXT: tail call void @free(i8* noalias [[TMP1]]) +; IS________OPM-NEXT: ret void +; +; IS________NPM-LABEL: define {{[^@]+}}@test1() +; IS________NPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 4) +; IS________NPM-NEXT: tail call void @nocapture_func_frees_pointer(i8* noalias nocapture [[TMP1]]) +; IS________NPM-NEXT: tail call void (...) @func_throws() +; IS________NPM-NEXT: tail call void @free(i8* noalias [[TMP1]]) +; IS________NPM-NEXT: ret void +; %1 = tail call noalias i8* @malloc(i64 4) - ; CHECK: @malloc(i64 4) - ; CHECK-NEXT: @nocapture_func_frees_pointer(i8* noalias nocapture %1) tail call void @nocapture_func_frees_pointer(i8* %1) tail call void (...) @func_throws() tail call void @free(i8* %1) @@ -46,9 +67,13 @@ define void @test1() { ; TEST 2 - negative, call to a sync function. define void @test2() { +; CHECK-LABEL: define {{[^@]+}}@test2() +; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 4) +; CHECK-NEXT: tail call void @sync_func(i8* [[TMP1]]) +; CHECK-NEXT: tail call void @free(i8* [[TMP1]]) +; CHECK-NEXT: ret void +; %1 = tail call noalias i8* @malloc(i64 4) - ; CHECK: @malloc(i64 4) - ; CHECK-NEXT: @sync_func(i8* %1) tail call void @sync_func(i8* %1) tail call void @free(i8* %1) ret void @@ -57,21 +82,46 @@ define void @test2() { ; TEST 3 - 1 malloc, 1 free define void @test3() { +; IS________OPM-LABEL: define {{[^@]+}}@test3() +; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 4) +; IS________OPM-NEXT: tail call void @no_sync_func(i8* noalias nofree [[TMP1]]) +; IS________OPM-NEXT: tail call void @free(i8* noalias [[TMP1]]) +; IS________OPM-NEXT: ret void +; +; IS________NPM-LABEL: define {{[^@]+}}@test3() +; IS________NPM-NEXT: [[TMP1:%.*]] = alloca i8, i64 4 +; IS________NPM-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree [[TMP1]]) +; IS________NPM-NEXT: ret void +; %1 = tail call noalias i8* @malloc(i64 4) - ; CHECK: %1 = alloca i8, i64 4 - ; CHECK-NEXT: @no_sync_func(i8* noalias nocapture nofree %1) tail call void @no_sync_func(i8* %1) - ; CHECK-NOT: @free(i8* %1) tail call void @free(i8* %1) ret void } define void @test3a(i8* %p) { +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@test3a +; IS__TUNIT_OPM-SAME: (i8* nocapture [[P:%.*]]) +; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 4) +; IS__TUNIT_OPM-NEXT: tail call void @nofree_arg_only(i8* nocapture nofree [[TMP1]], i8* nocapture [[P]]) +; IS__TUNIT_OPM-NEXT: tail call void @free(i8* noalias [[TMP1]]) +; IS__TUNIT_OPM-NEXT: ret void +; +; IS________NPM-LABEL: define {{[^@]+}}@test3a +; IS________NPM-SAME: (i8* nocapture [[P:%.*]]) +; IS________NPM-NEXT: [[TMP1:%.*]] = alloca i8, i64 4 +; IS________NPM-NEXT: tail call void @nofree_arg_only(i8* noalias nocapture nofree [[TMP1]], i8* nocapture [[P]]) +; IS________NPM-NEXT: ret void +; +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test3a +; IS__CGSCC_OPM-SAME: (i8* nocapture [[P:%.*]]) +; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 4) +; IS__CGSCC_OPM-NEXT: tail call void @nofree_arg_only(i8* nofree [[TMP1]], i8* nocapture [[P]]) +; IS__CGSCC_OPM-NEXT: tail call void @free(i8* noalias [[TMP1]]) +; IS__CGSCC_OPM-NEXT: ret void +; %1 = tail call noalias i8* @malloc(i64 4) - ; CHECK: %1 = alloca i8, i64 4 - ; CHECK-NEXT: tail call void @nofree_arg_only tail call void @nofree_arg_only(i8* %1, i8* %p) - ; CHECK-NOT: @free(i8* %1) tail call void @free(i8* %1) ret void } @@ -79,19 +129,41 @@ define void @test3a(i8* %p) { declare noalias i8* @aligned_alloc(i64, i64) define void @test3b(i8* %p) { +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@test3b +; IS__TUNIT_OPM-SAME: (i8* nocapture [[P:%.*]]) +; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @aligned_alloc(i64 32, i64 128) +; IS__TUNIT_OPM-NEXT: tail call void @nofree_arg_only(i8* nocapture nofree [[TMP1]], i8* nocapture [[P]]) +; IS__TUNIT_OPM-NEXT: tail call void @free(i8* noalias [[TMP1]]) +; IS__TUNIT_OPM-NEXT: ret void +; +; IS________NPM-LABEL: define {{[^@]+}}@test3b +; IS________NPM-SAME: (i8* nocapture [[P:%.*]]) +; IS________NPM-NEXT: [[TMP1:%.*]] = alloca i8, i64 128, align 32 +; IS________NPM-NEXT: tail call void @nofree_arg_only(i8* noalias nocapture nofree [[TMP1]], i8* nocapture [[P]]) +; IS________NPM-NEXT: ret void +; +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test3b +; IS__CGSCC_OPM-SAME: (i8* nocapture [[P:%.*]]) +; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @aligned_alloc(i64 32, i64 128) +; IS__CGSCC_OPM-NEXT: tail call void @nofree_arg_only(i8* nofree [[TMP1]], i8* nocapture [[P]]) +; IS__CGSCC_OPM-NEXT: tail call void @free(i8* noalias [[TMP1]]) +; IS__CGSCC_OPM-NEXT: ret void +; %1 = tail call noalias i8* @aligned_alloc(i64 32, i64 128) - ; CHECK: %1 = alloca i8, i64 128, align 32 - ; CHECK-NEXT: tail call void @nofree_arg_only tail call void @nofree_arg_only(i8* %1, i8* %p) - ; CHECK-NOT: @free(i8* %1) tail call void @free(i8* %1) ret void } ; leave alone non-constant alignments. define void @test3c(i64 %alignment) { +; CHECK-LABEL: define {{[^@]+}}@test3c +; CHECK-SAME: (i64 [[ALIGNMENT:%.*]]) +; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @aligned_alloc(i64 [[ALIGNMENT]], i64 128) +; CHECK-NEXT: tail call void @free(i8* noalias [[TMP1]]) +; CHECK-NEXT: ret void +; %1 = tail call noalias i8* @aligned_alloc(i64 %alignment, i64 128) - ; CHECK: tail call noalias i8* @aligned_alloc tail call void @free(i8* %1) ret void } @@ -99,22 +171,38 @@ define void @test3c(i64 %alignment) { declare noalias i8* @calloc(i64, i64) define void @test0() { +; IS________OPM-LABEL: define {{[^@]+}}@test0() +; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @calloc(i64 2, i64 4) +; IS________OPM-NEXT: tail call void @no_sync_func(i8* noalias nofree [[TMP1]]) +; IS________OPM-NEXT: tail call void @free(i8* noalias [[TMP1]]) +; IS________OPM-NEXT: ret void +; +; IS________NPM-LABEL: define {{[^@]+}}@test0() +; IS________NPM-NEXT: [[TMP1:%.*]] = alloca i8, i64 8 +; IS________NPM-NEXT: [[CALLOC_BC:%.*]] = bitcast i8* [[TMP1]] to i8* +; IS________NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* [[CALLOC_BC]], i8 0, i64 8, i1 false) +; IS________NPM-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree [[TMP1]]) +; IS________NPM-NEXT: ret void +; %1 = tail call noalias i8* @calloc(i64 2, i64 4) - ; CHECK: %1 = alloca i8, i64 8 - ; CHECK-NEXT: %calloc_bc = bitcast i8* %1 to i8* - ; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* %calloc_bc, i8 0, i64 8, i1 false) - ; CHECK-NEXT: @no_sync_func(i8* noalias nocapture nofree %1) tail call void @no_sync_func(i8* %1) - ; CHECK-NOT: @free(i8* %1) tail call void @free(i8* %1) ret void } ; TEST 4 define void @test4() { +; IS________OPM-LABEL: define {{[^@]+}}@test4() +; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 4) +; IS________OPM-NEXT: tail call void @nofree_func(i8* noalias nofree [[TMP1]]) +; IS________OPM-NEXT: ret void +; +; IS________NPM-LABEL: define {{[^@]+}}@test4() +; IS________NPM-NEXT: [[TMP1:%.*]] = alloca i8, i64 4 +; IS________NPM-NEXT: tail call void @nofree_func(i8* noalias nocapture nofree [[TMP1]]) +; IS________NPM-NEXT: ret void +; %1 = tail call noalias i8* @malloc(i64 4) - ; CHECK: %1 = alloca i8, i64 4 - ; CHECK-NEXT: @nofree_func(i8* noalias nocapture nofree %1) tail call void @nofree_func(i8* %1) ret void } @@ -123,9 +211,51 @@ define void @test4() { ; are in nofree functions and are not captured define void @test5(i32, i8* %p) { +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@test5 +; IS__TUNIT_OPM-SAME: (i32 [[TMP0:%.*]], i8* nocapture [[P:%.*]]) +; IS__TUNIT_OPM-NEXT: [[TMP2:%.*]] = tail call noalias i8* @malloc(i64 4) +; IS__TUNIT_OPM-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP0]], 0 +; IS__TUNIT_OPM-NEXT: br i1 [[TMP3]], label [[TMP5:%.*]], label [[TMP4:%.*]] +; IS__TUNIT_OPM: 4: +; IS__TUNIT_OPM-NEXT: tail call void @nofree_func(i8* noalias nofree [[TMP2]]) +; IS__TUNIT_OPM-NEXT: br label [[TMP6:%.*]] +; IS__TUNIT_OPM: 5: +; IS__TUNIT_OPM-NEXT: tail call void @nofree_arg_only(i8* nocapture nofree [[TMP2]], i8* nocapture [[P]]) +; IS__TUNIT_OPM-NEXT: tail call void @free(i8* noalias [[TMP2]]) +; IS__TUNIT_OPM-NEXT: br label [[TMP6]] +; IS__TUNIT_OPM: 6: +; IS__TUNIT_OPM-NEXT: ret void +; +; IS________NPM-LABEL: define {{[^@]+}}@test5 +; IS________NPM-SAME: (i32 [[TMP0:%.*]], i8* nocapture [[P:%.*]]) +; IS________NPM-NEXT: [[TMP2:%.*]] = alloca i8, i64 4 +; IS________NPM-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP0]], 0 +; IS________NPM-NEXT: br i1 [[TMP3]], label [[TMP5:%.*]], label [[TMP4:%.*]] +; IS________NPM: 4: +; IS________NPM-NEXT: tail call void @nofree_func(i8* noalias nocapture nofree [[TMP2]]) +; IS________NPM-NEXT: br label [[TMP6:%.*]] +; IS________NPM: 5: +; IS________NPM-NEXT: tail call void @nofree_arg_only(i8* noalias nocapture nofree [[TMP2]], i8* nocapture [[P]]) +; IS________NPM-NEXT: br label [[TMP6]] +; IS________NPM: 6: +; IS________NPM-NEXT: ret void +; +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test5 +; IS__CGSCC_OPM-SAME: (i32 [[TMP0:%.*]], i8* nocapture [[P:%.*]]) +; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = tail call noalias i8* @malloc(i64 4) +; IS__CGSCC_OPM-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP0]], 0 +; IS__CGSCC_OPM-NEXT: br i1 [[TMP3]], label [[TMP5:%.*]], label [[TMP4:%.*]] +; IS__CGSCC_OPM: 4: +; IS__CGSCC_OPM-NEXT: tail call void @nofree_func(i8* noalias nofree [[TMP2]]) +; IS__CGSCC_OPM-NEXT: br label [[TMP6:%.*]] +; IS__CGSCC_OPM: 5: +; IS__CGSCC_OPM-NEXT: tail call void @nofree_arg_only(i8* nofree [[TMP2]], i8* nocapture [[P]]) +; IS__CGSCC_OPM-NEXT: tail call void @free(i8* noalias [[TMP2]]) +; IS__CGSCC_OPM-NEXT: br label [[TMP6]] +; IS__CGSCC_OPM: 6: +; IS__CGSCC_OPM-NEXT: ret void +; %2 = tail call noalias i8* @malloc(i64 4) - ; CHECK: %2 = alloca i8, i64 4 - ; CHECK-NEXT: icmp eq i32 %0, 0 %3 = icmp eq i32 %0, 0 br i1 %3, label %5, label %4 @@ -136,7 +266,6 @@ define void @test5(i32, i8* %p) { 5: ; preds = %1 tail call void @nofree_arg_only(i8* %2, i8* %p) tail call void @free(i8* %2) - ; CHECK-NOT: @free(i8* %2) br label %6 6: ; preds = %5, %4 @@ -146,21 +275,45 @@ define void @test5(i32, i8* %p) { ; TEST 6 - all exit paths have a call to free define void @test6(i32) { +; IS________OPM-LABEL: define {{[^@]+}}@test6 +; IS________OPM-SAME: (i32 [[TMP0:%.*]]) +; IS________OPM-NEXT: [[TMP2:%.*]] = tail call noalias i8* @malloc(i64 4) +; IS________OPM-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP0]], 0 +; IS________OPM-NEXT: br i1 [[TMP3]], label [[TMP5:%.*]], label [[TMP4:%.*]] +; IS________OPM: 4: +; IS________OPM-NEXT: tail call void @nofree_func(i8* noalias nofree [[TMP2]]) +; IS________OPM-NEXT: tail call void @free(i8* noalias [[TMP2]]) +; IS________OPM-NEXT: br label [[TMP6:%.*]] +; IS________OPM: 5: +; IS________OPM-NEXT: tail call void @free(i8* noalias [[TMP2]]) +; IS________OPM-NEXT: br label [[TMP6]] +; IS________OPM: 6: +; IS________OPM-NEXT: ret void +; +; IS________NPM-LABEL: define {{[^@]+}}@test6 +; IS________NPM-SAME: (i32 [[TMP0:%.*]]) +; IS________NPM-NEXT: [[TMP2:%.*]] = alloca i8, i64 4 +; IS________NPM-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP0]], 0 +; IS________NPM-NEXT: br i1 [[TMP3]], label [[TMP5:%.*]], label [[TMP4:%.*]] +; IS________NPM: 4: +; IS________NPM-NEXT: tail call void @nofree_func(i8* noalias nocapture nofree [[TMP2]]) +; IS________NPM-NEXT: br label [[TMP6:%.*]] +; IS________NPM: 5: +; IS________NPM-NEXT: br label [[TMP6]] +; IS________NPM: 6: +; IS________NPM-NEXT: ret void +; %2 = tail call noalias i8* @malloc(i64 4) - ; CHECK: %2 = alloca i8, i64 4 - ; CHECK-NEXT: icmp eq i32 %0, 0 %3 = icmp eq i32 %0, 0 br i1 %3, label %5, label %4 4: ; preds = %1 tail call void @nofree_func(i8* %2) tail call void @free(i8* %2) - ; CHECK-NOT: @free(i8* %2) br label %6 5: ; preds = %1 tail call void @free(i8* %2) - ; CHECK-NOT: @free(i8* %2) br label %6 6: ; preds = %5, %4 @@ -170,11 +323,18 @@ define void @test6(i32) { ; TEST 7 - free is dead. define void @test7() { +; IS________OPM-LABEL: define {{[^@]+}}@test7() +; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 4) +; IS________OPM-NEXT: [[TMP2:%.*]] = tail call i32 @no_return_call() +; IS________OPM-NEXT: unreachable +; +; IS________NPM-LABEL: define {{[^@]+}}@test7() +; IS________NPM-NEXT: [[TMP1:%.*]] = alloca i8, i64 4 +; IS________NPM-NEXT: [[TMP2:%.*]] = tail call i32 @no_return_call() +; IS________NPM-NEXT: unreachable +; %1 = tail call noalias i8* @malloc(i64 4) - ; CHECK: alloca i8, i64 4 - ; CHECK-NEXT: tail call i32 @no_return_call() tail call i32 @no_return_call() - ; CHECK-NOT: @free(i8* %1) tail call void @free(i8* %1) ret void } @@ -182,30 +342,42 @@ define void @test7() { ; TEST 8 - Negative: bitcast pointer used in capture function define void @test8() { +; CHECK-LABEL: define {{[^@]+}}@test8() +; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 4) +; CHECK-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree [[TMP1]]) +; CHECK-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32* +; CHECK-NEXT: store i32 10, i32* [[TMP2]], align 4 +; CHECK-NEXT: tail call void @foo(i32* align 4 [[TMP2]]) +; CHECK-NEXT: tail call void @free(i8* nonnull align 4 dereferenceable(4) [[TMP1]]) +; CHECK-NEXT: ret void +; %1 = tail call noalias i8* @malloc(i64 4) - ; CHECK: %1 = tail call noalias i8* @malloc(i64 4) - ; CHECK-NEXT: @no_sync_func(i8* noalias nocapture nofree %1) tail call void @no_sync_func(i8* %1) %2 = bitcast i8* %1 to i32* store i32 10, i32* %2 %3 = load i32, i32* %2 tail call void @foo(i32* %2) - ; CHECK: @free(i8* nonnull align 4 dereferenceable(4) %1) tail call void @free(i8* %1) ret void } ; TEST 9 - FIXME: malloc should be converted. define void @test9() { +; CHECK-LABEL: define {{[^@]+}}@test9() +; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 4) +; CHECK-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree [[TMP1]]) +; CHECK-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32* +; CHECK-NEXT: store i32 10, i32* [[TMP2]], align 4 +; CHECK-NEXT: tail call void @foo_nounw(i32* nofree align 4 [[TMP2]]) +; CHECK-NEXT: tail call void @free(i8* nonnull align 4 dereferenceable(4) [[TMP1]]) +; CHECK-NEXT: ret void +; %1 = tail call noalias i8* @malloc(i64 4) - ; CHECK: %1 = tail call noalias i8* @malloc(i64 4) - ; CHECK-NEXT: @no_sync_func(i8* noalias nocapture nofree %1) tail call void @no_sync_func(i8* %1) %2 = bitcast i8* %1 to i32* store i32 10, i32* %2 %3 = load i32, i32* %2 tail call void @foo_nounw(i32* %2) - ; CHECK: @free(i8* nonnull align 4 dereferenceable(4) %1) tail call void @free(i8* %1) ret void } @@ -213,28 +385,58 @@ define void @test9() { ; TEST 10 - 1 malloc, 1 free define i32 @test10() { +; IS________OPM-LABEL: define {{[^@]+}}@test10() +; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 4) +; IS________OPM-NEXT: tail call void @no_sync_func(i8* noalias nofree [[TMP1]]) +; IS________OPM-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32* +; IS________OPM-NEXT: store i32 10, i32* [[TMP2]], align 4 +; IS________OPM-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4 +; IS________OPM-NEXT: tail call void @free(i8* noalias nonnull align 4 dereferenceable(4) [[TMP1]]) +; IS________OPM-NEXT: ret i32 [[TMP3]] +; +; IS________NPM-LABEL: define {{[^@]+}}@test10() +; IS________NPM-NEXT: [[TMP1:%.*]] = alloca i8, i64 4 +; IS________NPM-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree [[TMP1]]) +; IS________NPM-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32* +; IS________NPM-NEXT: store i32 10, i32* [[TMP2]], align 4 +; IS________NPM-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4 +; IS________NPM-NEXT: ret i32 [[TMP3]] +; %1 = tail call noalias i8* @malloc(i64 4) - ; CHECK: %1 = alloca i8, i64 4 - ; CHECK-NEXT: @no_sync_func(i8* noalias nocapture nofree %1) tail call void @no_sync_func(i8* %1) %2 = bitcast i8* %1 to i32* store i32 10, i32* %2 %3 = load i32, i32* %2 - ; CHECK-NOT: @free(i8* %1) tail call void @free(i8* %1) ret i32 %3 } define i32 @test_lifetime() { +; IS________OPM-LABEL: define {{[^@]+}}@test_lifetime() +; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 4) +; IS________OPM-NEXT: tail call void @no_sync_func(i8* noalias nofree [[TMP1]]) +; IS________OPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* noalias nonnull align 4 dereferenceable(4) [[TMP1]]) +; IS________OPM-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32* +; IS________OPM-NEXT: store i32 10, i32* [[TMP2]], align 4 +; IS________OPM-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4 +; IS________OPM-NEXT: tail call void @free(i8* noalias nonnull align 4 dereferenceable(4) [[TMP1]]) +; IS________OPM-NEXT: ret i32 [[TMP3]] +; +; IS________NPM-LABEL: define {{[^@]+}}@test_lifetime() +; IS________NPM-NEXT: [[TMP1:%.*]] = alloca i8, i64 4 +; IS________NPM-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree [[TMP1]]) +; IS________NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* noalias nonnull align 4 dereferenceable(4) [[TMP1]]) +; IS________NPM-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32* +; IS________NPM-NEXT: store i32 10, i32* [[TMP2]], align 4 +; IS________NPM-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4 +; IS________NPM-NEXT: ret i32 [[TMP3]] +; %1 = tail call noalias i8* @malloc(i64 4) - ; CHECK: %1 = alloca i8, i64 4 - ; CHECK-NEXT: @no_sync_func(i8* noalias nocapture nofree %1) tail call void @no_sync_func(i8* %1) call void @llvm.lifetime.start.p0i8(i64 4, i8* %1) %2 = bitcast i8* %1 to i32* store i32 10, i32* %2 %3 = load i32, i32* %2 - ; CHECK-NOT: @free(i8* %1) tail call void @free(i8* %1) ret i32 %3 } @@ -242,10 +444,18 @@ define i32 @test_lifetime() { ; TEST 11 define void @test11() { +; IS________OPM-LABEL: define {{[^@]+}}@test11() +; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 4) +; IS________OPM-NEXT: tail call void @sync_will_return(i8* [[TMP1]]) +; IS________OPM-NEXT: tail call void @free(i8* [[TMP1]]) +; IS________OPM-NEXT: ret void +; +; IS________NPM-LABEL: define {{[^@]+}}@test11() +; IS________NPM-NEXT: [[TMP1:%.*]] = alloca i8, i64 4 +; IS________NPM-NEXT: tail call void @sync_will_return(i8* [[TMP1]]) +; IS________NPM-NEXT: ret void +; %1 = tail call noalias i8* @malloc(i64 4) - ; CHECK: test11 - ; CHECK-NEXT: alloc - ; CHECK-NEXT: @sync_will_return(i8* %1) tail call void @sync_will_return(i8* %1) tail call void @free(i8* %1) ret void @@ -253,8 +463,67 @@ define void @test11() { ; TEST 12 define i32 @irreducible_cfg(i32 %0) { - ; CHECK: alloca i8, i64 4 - ; CHECK-NEXT: %3 = bitcast +; IS________OPM-LABEL: define {{[^@]+}}@irreducible_cfg +; IS________OPM-SAME: (i32 [[TMP0:%.*]]) +; IS________OPM-NEXT: [[TMP2:%.*]] = call noalias i8* @malloc(i64 4) +; IS________OPM-NEXT: [[TMP3:%.*]] = bitcast i8* [[TMP2]] to i32* +; IS________OPM-NEXT: store i32 10, i32* [[TMP3]], align 4 +; IS________OPM-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP0]], 1 +; IS________OPM-NEXT: br i1 [[TMP4]], label [[TMP5:%.*]], label [[TMP7:%.*]] +; IS________OPM: 5: +; IS________OPM-NEXT: [[TMP6:%.*]] = add nsw i32 [[TMP0]], 5 +; IS________OPM-NEXT: br label [[TMP13:%.*]] +; IS________OPM: 7: +; IS________OPM-NEXT: br label [[TMP8:%.*]] +; IS________OPM: 8: +; IS________OPM-NEXT: [[DOT0:%.*]] = phi i32 [ [[TMP14:%.*]], [[TMP13]] ], [ 1, [[TMP7]] ] +; IS________OPM-NEXT: [[TMP9:%.*]] = load i32, i32* [[TMP3]], align 4 +; IS________OPM-NEXT: [[TMP10:%.*]] = add nsw i32 [[TMP9]], -1 +; IS________OPM-NEXT: store i32 [[TMP10]], i32* [[TMP3]], align 4 +; IS________OPM-NEXT: [[TMP11:%.*]] = icmp ne i32 [[TMP9]], 0 +; IS________OPM-NEXT: br i1 [[TMP11]], label [[TMP12:%.*]], label [[TMP15:%.*]] +; IS________OPM: 12: +; IS________OPM-NEXT: br label [[TMP13]] +; IS________OPM: 13: +; IS________OPM-NEXT: [[DOT1:%.*]] = phi i32 [ [[TMP6]], [[TMP5]] ], [ [[DOT0]], [[TMP12]] ] +; IS________OPM-NEXT: [[TMP14]] = add nsw i32 [[DOT1]], 1 +; IS________OPM-NEXT: br label [[TMP8]] +; IS________OPM: 15: +; IS________OPM-NEXT: [[TMP16:%.*]] = bitcast i32* [[TMP3]] to i8* +; IS________OPM-NEXT: call void @free(i8* [[TMP16]]) +; IS________OPM-NEXT: [[TMP17:%.*]] = load i32, i32* [[TMP3]], align 4 +; IS________OPM-NEXT: ret i32 [[TMP17]] +; +; IS________NPM-LABEL: define {{[^@]+}}@irreducible_cfg +; IS________NPM-SAME: (i32 [[TMP0:%.*]]) +; IS________NPM-NEXT: [[TMP2:%.*]] = alloca i8, i64 4 +; IS________NPM-NEXT: [[TMP3:%.*]] = bitcast i8* [[TMP2]] to i32* +; IS________NPM-NEXT: store i32 10, i32* [[TMP3]], align 4 +; IS________NPM-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP0]], 1 +; IS________NPM-NEXT: br i1 [[TMP4]], label [[TMP5:%.*]], label [[TMP7:%.*]] +; IS________NPM: 5: +; IS________NPM-NEXT: [[TMP6:%.*]] = add nsw i32 [[TMP0]], 5 +; IS________NPM-NEXT: br label [[TMP13:%.*]] +; IS________NPM: 7: +; IS________NPM-NEXT: br label [[TMP8:%.*]] +; IS________NPM: 8: +; IS________NPM-NEXT: [[DOT0:%.*]] = phi i32 [ [[TMP14:%.*]], [[TMP13]] ], [ 1, [[TMP7]] ] +; IS________NPM-NEXT: [[TMP9:%.*]] = load i32, i32* [[TMP3]], align 4 +; IS________NPM-NEXT: [[TMP10:%.*]] = add nsw i32 [[TMP9]], -1 +; IS________NPM-NEXT: store i32 [[TMP10]], i32* [[TMP3]], align 4 +; IS________NPM-NEXT: [[TMP11:%.*]] = icmp ne i32 [[TMP9]], 0 +; IS________NPM-NEXT: br i1 [[TMP11]], label [[TMP12:%.*]], label [[TMP15:%.*]] +; IS________NPM: 12: +; IS________NPM-NEXT: br label [[TMP13]] +; IS________NPM: 13: +; IS________NPM-NEXT: [[DOT1:%.*]] = phi i32 [ [[TMP6]], [[TMP5]] ], [ [[DOT0]], [[TMP12]] ] +; IS________NPM-NEXT: [[TMP14]] = add nsw i32 [[DOT1]], 1 +; IS________NPM-NEXT: br label [[TMP8]] +; IS________NPM: 15: +; IS________NPM-NEXT: [[TMP16:%.*]] = bitcast i32* [[TMP3]] to i8* +; IS________NPM-NEXT: [[TMP17:%.*]] = load i32, i32* [[TMP3]], align 4 +; IS________NPM-NEXT: ret i32 [[TMP17]] +; %2 = call noalias i8* @malloc(i64 4) %3 = bitcast i8* %2 to i32* store i32 10, i32* %3, align 4 @@ -294,6 +563,46 @@ define i32 @irreducible_cfg(i32 %0) { define i32 @malloc_in_loop(i32 %0) { +; IS________OPM-LABEL: define {{[^@]+}}@malloc_in_loop +; IS________OPM-SAME: (i32 [[TMP0:%.*]]) +; IS________OPM-NEXT: [[TMP2:%.*]] = alloca i32, align 4 +; IS________OPM-NEXT: [[TMP3:%.*]] = alloca i32*, align 8 +; IS________OPM-NEXT: store i32 [[TMP0]], i32* [[TMP2]], align 4 +; IS________OPM-NEXT: br label [[TMP4:%.*]] +; IS________OPM: 4: +; IS________OPM-NEXT: [[TMP5:%.*]] = load i32, i32* [[TMP2]], align 4 +; IS________OPM-NEXT: [[TMP6:%.*]] = add nsw i32 [[TMP5]], -1 +; IS________OPM-NEXT: store i32 [[TMP6]], i32* [[TMP2]], align 4 +; IS________OPM-NEXT: [[TMP7:%.*]] = icmp sgt i32 [[TMP6]], 0 +; IS________OPM-NEXT: br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP11:%.*]] +; IS________OPM: 8: +; IS________OPM-NEXT: [[TMP9:%.*]] = call noalias i8* @malloc(i64 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 +; +; IS________NPM-LABEL: define {{[^@]+}}@malloc_in_loop +; IS________NPM-SAME: (i32 [[TMP0:%.*]]) +; IS________NPM-NEXT: [[TMP2:%.*]] = alloca i32, align 4 +; IS________NPM-NEXT: [[TMP3:%.*]] = alloca i32*, align 8 +; IS________NPM-NEXT: store i32 [[TMP0]], i32* [[TMP2]], align 4 +; IS________NPM-NEXT: br label [[TMP4:%.*]] +; IS________NPM: 4: +; IS________NPM-NEXT: [[TMP5:%.*]] = load i32, i32* [[TMP2]], align 4 +; IS________NPM-NEXT: [[TMP6:%.*]] = add nsw i32 [[TMP5]], -1 +; IS________NPM-NEXT: store i32 [[TMP6]], i32* [[TMP2]], align 4 +; IS________NPM-NEXT: [[TMP7:%.*]] = icmp sgt i32 [[TMP6]], 0 +; IS________NPM-NEXT: br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP11:%.*]] +; IS________NPM: 8: +; IS________NPM-NEXT: [[TMP9:%.*]] = alloca i8, i64 4 +; IS________NPM-NEXT: [[TMP10:%.*]] = bitcast i8* [[TMP9]] to i32* +; IS________NPM-NEXT: store i32 1, i32* [[TMP10]], align 8 +; IS________NPM-NEXT: br label [[TMP4]] +; IS________NPM: 11: +; IS________NPM-NEXT: ret i32 5 +; %2 = alloca i32, align 4 %3 = alloca i32*, align 8 store i32 %0, i32* %2, align 4 @@ -308,7 +617,6 @@ define i32 @malloc_in_loop(i32 %0) { 8: ; preds = %4 %9 = call noalias i8* @malloc(i64 4) - ; CHECK: alloca i8, i64 4 %10 = bitcast i8* %9 to i32* store i32 1, i32* %10, align 8 br label %4 @@ -319,104 +627,167 @@ define i32 @malloc_in_loop(i32 %0) { ; Malloc/Calloc too large define i32 @test13() { +; CHECK-LABEL: define {{[^@]+}}@test13() +; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 256) +; CHECK-NEXT: tail call void @no_sync_func(i8* noalias nofree [[TMP1]]) +; CHECK-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32* +; CHECK-NEXT: store i32 10, i32* [[TMP2]], align 4 +; CHECK-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4 +; CHECK-NEXT: tail call void @free(i8* noalias nonnull align 4 dereferenceable(4) [[TMP1]]) +; CHECK-NEXT: ret i32 [[TMP3]] +; %1 = tail call noalias i8* @malloc(i64 256) - ; CHECK: %1 = tail call noalias i8* @malloc(i64 256) - ; CHECK-NEXT: @no_sync_func(i8* noalias nofree %1) tail call void @no_sync_func(i8* %1) %2 = bitcast i8* %1 to i32* store i32 10, i32* %2 %3 = load i32, i32* %2 tail call void @free(i8* %1) - ; CHECK: tail call void @free(i8* noalias nonnull align 4 dereferenceable(4) %1) ret i32 %3 } define i32 @test_sle() { +; CHECK-LABEL: define {{[^@]+}}@test_sle() +; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 -1) +; CHECK-NEXT: tail call void @no_sync_func(i8* noalias nofree [[TMP1]]) +; CHECK-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32* +; CHECK-NEXT: store i32 10, i32* [[TMP2]], align 4 +; CHECK-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4 +; CHECK-NEXT: tail call void @free(i8* noalias nonnull align 4 dereferenceable(4) [[TMP1]]) +; CHECK-NEXT: ret i32 [[TMP3]] +; %1 = tail call noalias i8* @malloc(i64 -1) - ; CHECK: %1 = tail call noalias i8* @malloc(i64 -1) - ; CHECK-NEXT: @no_sync_func(i8* noalias nofree %1) tail call void @no_sync_func(i8* %1) %2 = bitcast i8* %1 to i32* store i32 10, i32* %2 %3 = load i32, i32* %2 tail call void @free(i8* %1) - ; CHECK: tail call void @free(i8* noalias nonnull align 4 dereferenceable(4) %1) ret i32 %3 } define i32 @test_overflow() { +; CHECK-LABEL: define {{[^@]+}}@test_overflow() +; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @calloc(i64 65537, i64 65537) +; CHECK-NEXT: tail call void @no_sync_func(i8* noalias nofree [[TMP1]]) +; CHECK-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32* +; CHECK-NEXT: store i32 10, i32* [[TMP2]], align 4 +; CHECK-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4 +; CHECK-NEXT: tail call void @free(i8* noalias nonnull align 4 dereferenceable(4) [[TMP1]]) +; CHECK-NEXT: ret i32 [[TMP3]] +; %1 = tail call noalias i8* @calloc(i64 65537, i64 65537) - ; CHECK: %1 = tail call noalias i8* @calloc(i64 65537, i64 65537) - ; CHECK-NEXT: @no_sync_func(i8* noalias nofree %1) tail call void @no_sync_func(i8* %1) %2 = bitcast i8* %1 to i32* store i32 10, i32* %2 %3 = load i32, i32* %2 tail call void @free(i8* %1) - ; CHECK: tail call void @free(i8* noalias nonnull align 4 dereferenceable(4) %1) ret i32 %3 } define void @test14() { +; CHECK-LABEL: define {{[^@]+}}@test14() +; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @calloc(i64 64, i64 4) +; CHECK-NEXT: tail call void @no_sync_func(i8* noalias nofree [[TMP1]]) +; CHECK-NEXT: tail call void @free(i8* noalias [[TMP1]]) +; CHECK-NEXT: ret void +; %1 = tail call noalias i8* @calloc(i64 64, i64 4) - ; CHECK: %1 = tail call noalias i8* @calloc(i64 64, i64 4) - ; CHECK-NEXT: @no_sync_func(i8* noalias nofree %1) tail call void @no_sync_func(i8* %1) tail call void @free(i8* %1) - ; CHECK: tail call void @free(i8* noalias %1) ret void } define void @test15(i64 %S) { - ; CHECK: %1 = tail call noalias i8* @malloc(i64 %S) +; CHECK-LABEL: define {{[^@]+}}@test15 +; CHECK-SAME: (i64 [[S:%.*]]) +; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 [[S]]) +; CHECK-NEXT: tail call void @no_sync_func(i8* noalias nofree [[TMP1]]) +; CHECK-NEXT: tail call void @free(i8* noalias [[TMP1]]) +; CHECK-NEXT: ret void +; %1 = tail call noalias i8* @malloc(i64 %S) - ; CHECK-NEXT: @no_sync_func(i8* noalias nofree %1) tail call void @no_sync_func(i8* %1) - ; CHECK-NEXT: @free(i8* noalias %1) tail call void @free(i8* %1) ret void } define void @test16a(i8 %v, i8** %P) { - ; CHECK: %1 = alloca +; IS________OPM-LABEL: define {{[^@]+}}@test16a +; IS________OPM-SAME: (i8 [[V:%.*]], i8** nocapture nofree readnone [[P:%.*]]) +; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 4) +; IS________OPM-NEXT: store i8 [[V]], i8* [[TMP1]] +; IS________OPM-NEXT: tail call void @no_sync_func(i8* noalias nofree nonnull dereferenceable(1) [[TMP1]]) +; IS________OPM-NEXT: tail call void @free(i8* noalias nonnull dereferenceable(1) [[TMP1]]) +; IS________OPM-NEXT: ret void +; +; IS________NPM-LABEL: define {{[^@]+}}@test16a +; IS________NPM-SAME: (i8 [[V:%.*]], i8** nocapture nofree readnone [[P:%.*]]) +; IS________NPM-NEXT: [[TMP1:%.*]] = alloca i8, i64 4 +; IS________NPM-NEXT: store i8 [[V]], i8* [[TMP1]] +; IS________NPM-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree nonnull dereferenceable(1) [[TMP1]]) +; IS________NPM-NEXT: ret void +; %1 = tail call noalias i8* @malloc(i64 4) - ; CHECK-NEXT: store i8 %v, i8* %1 store i8 %v, i8* %1 - ; CHECK-NEXT: @no_sync_func(i8* noalias nocapture nofree nonnull dereferenceable(1) %1) tail call void @no_sync_func(i8* %1) - ; CHECK-NOT: @free(i8* %1) tail call void @free(i8* nonnull dereferenceable(1) %1) ret void } define void @test16b(i8 %v, i8** %P) { - ; CHECK: %1 = tail call noalias i8* @malloc(i64 4) +; IS________OPM-LABEL: define {{[^@]+}}@test16b +; IS________OPM-SAME: (i8 [[V:%.*]], i8** nocapture writeonly [[P:%.*]]) +; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 4) +; IS________OPM-NEXT: store i8* [[TMP1]], i8** [[P]] +; IS________OPM-NEXT: tail call void @no_sync_func(i8* nofree [[TMP1]]) +; IS________OPM-NEXT: tail call void @free(i8* [[TMP1]]) +; IS________OPM-NEXT: ret void +; +; IS________NPM-LABEL: define {{[^@]+}}@test16b +; IS________NPM-SAME: (i8 [[V:%.*]], i8** nocapture writeonly [[P:%.*]]) +; IS________NPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 4) +; IS________NPM-NEXT: store i8* [[TMP1]], i8** [[P]] +; IS________NPM-NEXT: tail call void @no_sync_func(i8* nocapture nofree [[TMP1]]) +; IS________NPM-NEXT: tail call void @free(i8* [[TMP1]]) +; IS________NPM-NEXT: ret void +; %1 = tail call noalias i8* @malloc(i64 4) - ; CHECK-NEXT: store i8* %1, i8** %P store i8* %1, i8** %P - ; CHECK-NEXT: @no_sync_func(i8* nocapture nofree %1) tail call void @no_sync_func(i8* %1) - ; CHECK-NEXT: @free(i8* %1) tail call void @free(i8* %1) ret void } define void @test16c(i8 %v, i8** %P) { - ; CHECK: %1 = alloca +; IS________OPM-LABEL: define {{[^@]+}}@test16c +; IS________OPM-SAME: (i8 [[V:%.*]], i8** nocapture writeonly [[P:%.*]]) +; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 4) +; IS________OPM-NEXT: store i8* [[TMP1]], i8** [[P]] +; IS________OPM-NEXT: tail call void @no_sync_func(i8* nofree [[TMP1]]) +; IS________OPM-NEXT: tail call void @free(i8* [[TMP1]]) +; IS________OPM-NEXT: ret void +; +; IS________NPM-LABEL: define {{[^@]+}}@test16c +; IS________NPM-SAME: (i8 [[V:%.*]], i8** nocapture writeonly [[P:%.*]]) +; IS________NPM-NEXT: [[TMP1:%.*]] = alloca i8, i64 4 +; IS________NPM-NEXT: store i8* [[TMP1]], i8** [[P]] +; IS________NPM-NEXT: tail call void @no_sync_func(i8* nocapture nofree [[TMP1]]) +; IS________NPM-NEXT: ret void +; %1 = tail call noalias i8* @malloc(i64 4) - ; CHECK-NEXT: store i8* %1, i8** %P store i8* %1, i8** %P - ; CHECK-NEXT: @no_sync_func(i8* nocapture nofree %1) tail call void @no_sync_func(i8* %1) nounwind - ; CHECK-NOT: @free tail call void @free(i8* %1) ret void } define void @test16d(i8 %v, i8** %P) { - ; CHECK: %1 = tail call noalias i8* @malloc(i64 4) +; CHECK-LABEL: define {{[^@]+}}@test16d +; CHECK-SAME: (i8 [[V:%.*]], i8** nocapture writeonly [[P:%.*]]) +; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 4) +; CHECK-NEXT: store i8* [[TMP1]], i8** [[P]] +; CHECK-NEXT: ret void +; %1 = tail call noalias i8* @malloc(i64 4) - ; CHECK-NEXT: store i8* %1, i8** %P store i8* %1, i8** %P ret void } diff --git a/llvm/test/Transforms/Attributor/internal-noalias.ll b/llvm/test/Transforms/Attributor/internal-noalias.ll index 600da85001bd..2df1c11d9bb9 100644 --- a/llvm/test/Transforms/Attributor/internal-noalias.ll +++ b/llvm/test/Transforms/Attributor/internal-noalias.ll @@ -1,6 +1,26 @@ -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=7 < %s | FileCheck %s +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=7 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=7 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 define dso_local i32 @visible(i32* noalias %A, i32* noalias %B) #0 { +; IS__TUNIT____-LABEL: define {{[^@]+}}@visible +; IS__TUNIT____-SAME: (i32* noalias nocapture nofree readonly [[A:%.*]], i32* noalias nocapture nofree readonly [[B:%.*]]) +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: [[CALL1:%.*]] = call i32 @noalias_args(i32* noalias nocapture nofree readonly align 4 [[A]], i32* noalias nocapture nofree readonly align 4 [[B]]) +; IS__TUNIT____-NEXT: [[CALL2:%.*]] = call i32 @noalias_args_argmem(i32* noalias nocapture nofree readonly align 4 [[A]], i32* noalias nocapture nofree readonly align 4 [[B]]) +; IS__TUNIT____-NEXT: [[ADD:%.*]] = add nsw i32 [[CALL1]], [[CALL2]] +; IS__TUNIT____-NEXT: ret i32 [[ADD]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@visible +; IS__CGSCC____-SAME: (i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A:%.*]], i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B:%.*]]) +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i32 @noalias_args(i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A]], i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B]]) +; IS__CGSCC____-NEXT: [[CALL2:%.*]] = call i32 @noalias_args_argmem(i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A]], i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B]]) +; IS__CGSCC____-NEXT: [[ADD:%.*]] = add nsw i32 [[CALL1]], [[CALL2]] +; IS__CGSCC____-NEXT: ret i32 [[ADD]] +; entry: %call1 = call i32 @noalias_args(i32* %A, i32* %B) %call2 = call i32 @noalias_args_argmem(i32* %A, i32* %B) @@ -8,9 +28,27 @@ entry: ret i32 %add } -; CHECK: define private i32 @noalias_args(i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) %A, i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) %B) - define private i32 @noalias_args(i32* %A, i32* %B) #0 { +; IS__TUNIT____-LABEL: define {{[^@]+}}@noalias_args +; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A:%.*]], i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B:%.*]]) +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: [[TMP0:%.*]] = load i32, i32* [[A]], align 4 +; IS__TUNIT____-NEXT: [[TMP1:%.*]] = load i32, i32* [[B]], align 4 +; IS__TUNIT____-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP0]], [[TMP1]] +; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32 @noalias_args_argmem(i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A]], i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B]]) +; IS__TUNIT____-NEXT: [[ADD2:%.*]] = add nsw i32 [[ADD]], [[CALL]] +; IS__TUNIT____-NEXT: ret i32 [[ADD2]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@noalias_args +; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A:%.*]], i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B:%.*]]) +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: [[TMP0:%.*]] = load i32, i32* [[A]], align 4 +; IS__CGSCC____-NEXT: [[TMP1:%.*]] = load i32, i32* [[B]], align 4 +; IS__CGSCC____-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP0]], [[TMP1]] +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32 @noalias_args_argmem(i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A]], i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B]]) +; IS__CGSCC____-NEXT: [[ADD2:%.*]] = add nsw i32 [[ADD]], [[CALL]] +; IS__CGSCC____-NEXT: ret i32 [[ADD2]] +; entry: %0 = load i32, i32* %A, align 4 %1 = load i32, i32* %B, align 4 @@ -21,8 +59,23 @@ entry: } -; CHECK: define internal i32 @noalias_args_argmem(i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) %A, i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) %B) define internal i32 @noalias_args_argmem(i32* %A, i32* %B) #1 { +; IS__TUNIT____-LABEL: define {{[^@]+}}@noalias_args_argmem +; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A:%.*]], i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B:%.*]]) +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: [[TMP0:%.*]] = load i32, i32* [[A]], align 4 +; IS__TUNIT____-NEXT: [[TMP1:%.*]] = load i32, i32* [[B]], align 4 +; IS__TUNIT____-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP0]], [[TMP1]] +; IS__TUNIT____-NEXT: ret i32 [[ADD]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@noalias_args_argmem +; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A:%.*]], i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B:%.*]]) +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: [[TMP0:%.*]] = load i32, i32* [[A]], align 4 +; IS__CGSCC____-NEXT: [[TMP1:%.*]] = load i32, i32* [[B]], align 4 +; IS__CGSCC____-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP0]], [[TMP1]] +; IS__CGSCC____-NEXT: ret i32 [[ADD]] +; entry: %0 = load i32, i32* %A, align 4 %1 = load i32, i32* %B, align 4 @@ -31,6 +84,26 @@ entry: } define dso_local i32 @visible_local(i32* %A) #0 { +; IS__TUNIT____-LABEL: define {{[^@]+}}@visible_local +; IS__TUNIT____-SAME: (i32* nocapture nofree readonly [[A:%.*]]) +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: [[B:%.*]] = alloca i32, align 4 +; IS__TUNIT____-NEXT: store i32 5, i32* [[B]], align 4 +; IS__TUNIT____-NEXT: [[CALL1:%.*]] = call i32 @noalias_args(i32* nocapture nofree readonly align 4 [[A]], i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B]]) +; IS__TUNIT____-NEXT: [[CALL2:%.*]] = call i32 @noalias_args_argmem(i32* nocapture nofree readonly align 4 [[A]], i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B]]) +; IS__TUNIT____-NEXT: [[ADD:%.*]] = add nsw i32 [[CALL1]], [[CALL2]] +; IS__TUNIT____-NEXT: ret i32 [[ADD]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@visible_local +; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: [[B:%.*]] = alloca i32, align 4 +; IS__CGSCC____-NEXT: store i32 5, i32* [[B]], align 4 +; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i32 @noalias_args(i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A]], i32* noalias nofree nonnull readonly align 4 dereferenceable(4) [[B]]) +; IS__CGSCC____-NEXT: [[CALL2:%.*]] = call i32 @noalias_args_argmem(i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A]], i32* noalias nofree nonnull readonly align 4 dereferenceable(4) [[B]]) +; IS__CGSCC____-NEXT: [[ADD:%.*]] = add nsw i32 [[CALL1]], [[CALL2]] +; IS__CGSCC____-NEXT: ret i32 [[ADD]] +; entry: %B = alloca i32, align 4 store i32 5, i32* %B, align 4 @@ -40,8 +113,32 @@ entry: ret i32 %add } -; CHECK: define internal i32 @noalias_args_argmem_ro(i32 %0, i32 %1) define internal i32 @noalias_args_argmem_ro(i32* %A, i32* %B) #1 { +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@noalias_args_argmem_ro +; IS__TUNIT_OPM-SAME: (i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A:%.*]], i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B:%.*]]) +; IS__TUNIT_OPM-NEXT: [[T0:%.*]] = load i32, i32* [[A]], align 4 +; IS__TUNIT_OPM-NEXT: [[T1:%.*]] = load i32, i32* [[B]], align 4 +; IS__TUNIT_OPM-NEXT: [[ADD:%.*]] = add nsw i32 [[T0]], [[T1]] +; IS__TUNIT_OPM-NEXT: ret i32 [[ADD]] +; +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@noalias_args_argmem_ro +; IS__TUNIT_NPM-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]]) +; IS__TUNIT_NPM-NEXT: [[B_PRIV:%.*]] = alloca i32 +; IS__TUNIT_NPM-NEXT: store i32 [[TMP1]], i32* [[B_PRIV]] +; IS__TUNIT_NPM-NEXT: [[A_PRIV:%.*]] = alloca i32 +; IS__TUNIT_NPM-NEXT: store i32 [[TMP0]], i32* [[A_PRIV]] +; IS__TUNIT_NPM-NEXT: [[T0:%.*]] = load i32, i32* [[A_PRIV]], align 4 +; IS__TUNIT_NPM-NEXT: [[T1:%.*]] = load i32, i32* [[B_PRIV]], align 4 +; IS__TUNIT_NPM-NEXT: [[ADD:%.*]] = add nsw i32 [[T0]], [[T1]] +; IS__TUNIT_NPM-NEXT: ret i32 [[ADD]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@noalias_args_argmem_ro +; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A:%.*]], i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B:%.*]]) +; IS__CGSCC____-NEXT: [[T0:%.*]] = load i32, i32* [[A]], align 4 +; IS__CGSCC____-NEXT: [[T1:%.*]] = load i32, i32* [[B]], align 4 +; IS__CGSCC____-NEXT: [[ADD:%.*]] = add nsw i32 [[T0]], [[T1]] +; IS__CGSCC____-NEXT: ret i32 [[ADD]] +; %t0 = load i32, i32* %A, align 4 %t1 = load i32, i32* %B, align 4 %add = add nsw i32 %t0, %t1 @@ -49,20 +146,63 @@ define internal i32 @noalias_args_argmem_ro(i32* %A, i32* %B) #1 { } define i32 @visible_local_2() { +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@visible_local_2() +; IS__TUNIT_OPM-NEXT: [[B:%.*]] = alloca i32, align 4 +; IS__TUNIT_OPM-NEXT: store i32 5, i32* [[B]], align 4 +; IS__TUNIT_OPM-NEXT: [[CALL:%.*]] = call i32 @noalias_args_argmem_ro(i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B]], i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B]]) +; IS__TUNIT_OPM-NEXT: ret i32 [[CALL]] +; +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@visible_local_2() +; IS__TUNIT_NPM-NEXT: [[B:%.*]] = alloca i32, align 4 +; IS__TUNIT_NPM-NEXT: store i32 5, i32* [[B]], align 4 +; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[B]], align 1 +; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[B]], align 1 +; IS__TUNIT_NPM-NEXT: [[CALL:%.*]] = call i32 @noalias_args_argmem_ro(i32 [[TMP1]], i32 [[TMP2]]) +; IS__TUNIT_NPM-NEXT: ret i32 [[CALL]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@visible_local_2() +; IS__CGSCC____-NEXT: [[B:%.*]] = alloca i32, align 4 +; IS__CGSCC____-NEXT: store i32 5, i32* [[B]], align 4 +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32 @noalias_args_argmem_ro(i32* noalias nofree nonnull readonly align 4 dereferenceable(4) [[B]], i32* noalias nofree nonnull readonly align 4 dereferenceable(4) [[B]]) +; IS__CGSCC____-NEXT: ret i32 [[CALL]] +; %B = alloca i32, align 4 store i32 5, i32* %B, align 4 %call = call i32 @noalias_args_argmem_ro(i32* %B, i32* %B) ret i32 %call } -; CHECK: define internal i32 @noalias_args_argmem_rn(i32* noalias nocapture nofree nonnull align 4 dereferenceable(4) %B) define internal i32 @noalias_args_argmem_rn(i32* %A, i32* %B) #1 { +; IS__TUNIT____-LABEL: define {{[^@]+}}@noalias_args_argmem_rn +; IS__TUNIT____-SAME: (i32* noalias nocapture nofree nonnull align 4 dereferenceable(4) [[B:%.*]]) +; IS__TUNIT____-NEXT: [[T0:%.*]] = load i32, i32* [[B]], align 4 +; IS__TUNIT____-NEXT: store i32 0, i32* [[B]], align 4 +; IS__TUNIT____-NEXT: ret i32 [[T0]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@noalias_args_argmem_rn +; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull align 4 dereferenceable(4) [[B:%.*]]) +; IS__CGSCC____-NEXT: [[T0:%.*]] = load i32, i32* [[B]], align 4 +; IS__CGSCC____-NEXT: store i32 0, i32* [[B]], align 4 +; IS__CGSCC____-NEXT: ret i32 [[T0]] +; %t0 = load i32, i32* %B, align 4 store i32 0, i32* %B ret i32 %t0 } define i32 @visible_local_3() { +; IS__TUNIT____-LABEL: define {{[^@]+}}@visible_local_3() +; IS__TUNIT____-NEXT: [[B:%.*]] = alloca i32, align 4 +; IS__TUNIT____-NEXT: store i32 5, i32* [[B]], align 4 +; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32 @noalias_args_argmem_rn(i32* noalias nocapture nofree nonnull align 4 dereferenceable(4) [[B]]) +; IS__TUNIT____-NEXT: ret i32 [[CALL]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@visible_local_3() +; IS__CGSCC____-NEXT: [[B:%.*]] = alloca i32, align 4 +; IS__CGSCC____-NEXT: store i32 5, i32* [[B]], align 4 +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32 @noalias_args_argmem_rn(i32* noalias nofree nonnull align 4 dereferenceable(4) [[B]]) +; IS__CGSCC____-NEXT: ret i32 [[CALL]] +; %B = alloca i32, align 4 store i32 5, i32* %B, align 4 %call = call i32 @noalias_args_argmem_rn(i32* %B, i32* %B) diff --git a/llvm/test/Transforms/Attributor/liveness.ll b/llvm/test/Transforms/Attributor/liveness.ll index 5b5aabb1ddcc..bfacc9a9dac0 100644 --- a/llvm/test/Transforms/Attributor/liveness.ll +++ b/llvm/test/Transforms/Attributor/liveness.ll @@ -1,15 +1,11 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes -; RUN: opt -attributor --attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=7 -S < %s | FileCheck %s --check-prefixes=CHECK,MODULE,MODULE_OLD -; RUN: opt -attributor-cgscc --attributor-disable=false -attributor-annotate-decl-cs -attributor-max-iterations=7 -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC,CGSCC_OLD -; RUN: opt -passes=attributor --attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=7 -S < %s | FileCheck %s --check-prefixes=CHECK,MODULE,MODULE_NEW -; RUN: opt -passes='attributor-cgscc' --attributor-disable=false -attributor-annotate-decl-cs -attributor-max-iterations=7 -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC,CGSCC_NEW -; XFAIL: * -; UTC_ARGS: --disable +; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=7 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=7 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 -; MODULE_OLD: @dead_with_blockaddress_users.l = constant [2 x i8*] [i8* inttoptr (i32 1 to i8*), i8* inttoptr (i32 1 to i8*)] -; MODULE_NEW: @dead_with_blockaddress_users.l = constant [2 x i8*] [i8* inttoptr (i32 1 to i8*), i8* inttoptr (i32 1 to i8*)] -; CGSCC_OLD: @dead_with_blockaddress_users.l = constant [2 x i8*] [i8* blockaddress(@dead_with_blockaddress_users, %lab0), i8* blockaddress(@dead_with_blockaddress_users, %end)] -; CGSCC_NEW: @dead_with_blockaddress_users.l = constant [2 x i8*] [i8* inttoptr (i32 1 to i8*), i8* inttoptr (i32 1 to i8*)] +; NOT_CGSCC_OPM: @dead_with_blockaddress_users.l = constant [2 x i8*] [i8* inttoptr (i32 1 to i8*), i8* inttoptr (i32 1 to i8*)] +; IS__CGSCC_OPM: @dead_with_blockaddress_users.l = constant [2 x i8*] [i8* blockaddress(@dead_with_blockaddress_users, %lab0), i8* blockaddress(@dead_with_blockaddress_users, %end)] @dead_with_blockaddress_users.l = constant [2 x i8*] [i8* blockaddress(@dead_with_blockaddress_users, %lab0), i8* blockaddress(@dead_with_blockaddress_users, %end)] declare void @no_return_call() nofree noreturn nounwind nosync @@ -29,8 +25,19 @@ declare i32 @bar() nosync readnone ; This internal function has no live call sites, so all its BBs are considered dead, ; and nothing should be deduced for it. -; MODULE-NOT: define internal i32 @dead_internal_func(i32 %0) define internal i32 @dead_internal_func(i32 %0) { +; IS__CGSCC____-LABEL: define {{[^@]+}}@dead_internal_func() +; IS__CGSCC____-NEXT: br label [[TMP2:%.*]] +; IS__CGSCC____: 1: +; IS__CGSCC____-NEXT: ret i32 undef +; IS__CGSCC____: 2: +; IS__CGSCC____-NEXT: [[TMP3:%.*]] = phi i32 [ [[TMP6:%.*]], [[TMP2]] ], [ 1, [[TMP0:%.*]] ] +; IS__CGSCC____-NEXT: [[TMP4:%.*]] = phi i32 [ [[TMP5:%.*]], [[TMP2]] ], [ 1, [[TMP0]] ] +; IS__CGSCC____-NEXT: [[TMP5]] = mul nsw i32 [[TMP3]], [[TMP4]] +; IS__CGSCC____-NEXT: [[TMP6]] = add nuw nsw i32 [[TMP3]], 1 +; IS__CGSCC____-NEXT: [[TMP7:%.*]] = icmp eq i32 [[TMP3]], 10 +; IS__CGSCC____-NEXT: br i1 [[TMP7]], label [[TMP1:%.*]], label [[TMP2]] +; %2 = icmp slt i32 %0, 1 br i1 %2, label %3, label %5 @@ -49,26 +56,41 @@ define internal i32 @dead_internal_func(i32 %0) { ; CHECK: Function Attrs: argmemonly nofree norecurse nounwind uwtable willreturn define i32 @volatile_load(i32*) norecurse nounwind uwtable { +; CHECK-LABEL: define {{[^@]+}}@volatile_load +; CHECK-SAME: (i32* nofree align 4 [[TMP0:%.*]]) +; CHECK-NEXT: [[TMP2:%.*]] = load volatile i32, i32* [[TMP0]], align 4 +; CHECK-NEXT: ret i32 [[TMP2]] +; %2 = load volatile i32, i32* %0, align 4 ret i32 %2 } -; MODULE-NOT: internal_load define internal i32 @internal_load(i32*) norecurse nounwind uwtable { +; IS__CGSCC____-LABEL: define {{[^@]+}}@internal_load() +; IS__CGSCC____-NEXT: ret i32 undef +; %2 = load i32, i32* %0, align 4 ret i32 %2 } ; TEST 1: Only first block is live. ; CHECK: Function Attrs: nofree noreturn nosync nounwind -; MODULE-NEXT: define i32 @first_block_no_return(i32 %a, i32* nocapture nofree nonnull readnone %ptr1, i32* nocapture nofree readnone %ptr2) -; CGSCC-NEXT: define i32 @first_block_no_return(i32 %a, i32* nocapture nofree nonnull readnone %ptr1, i32* nocapture nofree readnone %ptr2) define i32 @first_block_no_return(i32 %a, i32* nonnull %ptr1, i32* %ptr2) #0 { +; CHECK-LABEL: define {{[^@]+}}@first_block_no_return +; CHECK-SAME: (i32 [[A:%.*]], i32* nocapture nofree nonnull readnone [[PTR1:%.*]], i32* nocapture nofree readnone [[PTR2:%.*]]) +; CHECK-NEXT: entry: +; CHECK-NEXT: call void @no_return_call() +; CHECK-NEXT: unreachable +; CHECK: cond.true: +; CHECK-NEXT: unreachable +; CHECK: cond.false: +; CHECK-NEXT: unreachable +; CHECK: cond.end: +; CHECK-NEXT: unreachable +; entry: call i32 @internal_load(i32* %ptr1) call void @no_return_call() - ; CHECK: call void @no_return_call() - ; CHECK-NEXT: unreachable call i32 @dead_internal_func(i32 10) %cmp = icmp eq i32 %a, 0 br i1 %cmp, label %cond.true, label %cond.false @@ -96,16 +118,28 @@ cond.end: ; preds = %cond.false, %cond.t ; dead block and check if it is deduced. ; CHECK: Function Attrs: nosync -; CHECK-NEXT: define i32 @dead_block_present(i32 %a, i32* nocapture nofree readnone %ptr1) define i32 @dead_block_present(i32 %a, i32* %ptr1) #0 { +; CHECK-LABEL: define {{[^@]+}}@dead_block_present +; CHECK-SAME: (i32 [[A:%.*]], i32* nocapture nofree readnone [[PTR1:%.*]]) +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A]], 0 +; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +; CHECK: cond.true: +; CHECK-NEXT: call void @no_return_call() +; CHECK-NEXT: unreachable +; CHECK: cond.false: +; CHECK-NEXT: call void @normal_call() +; CHECK-NEXT: [[CALL1:%.*]] = call i32 @bar() +; CHECK-NEXT: br label [[COND_END:%.*]] +; CHECK: cond.end: +; CHECK-NEXT: ret i32 [[CALL1]] +; entry: %cmp = icmp eq i32 %a, 0 br i1 %cmp, label %cond.true, label %cond.false cond.true: ; preds = %entry call void @no_return_call() - ; CHECK: call void @no_return_call() - ; CHECK-NEXT: unreachable %call = call i32 @volatile_load(i32* %ptr1) br label %cond.end @@ -115,8 +149,6 @@ cond.false: ; preds = %entry br label %cond.end cond.end: ; preds = %cond.false, %cond.true -; CHECK: cond.end: -; CHECK-NEXT: ret i32 %call1 %cond = phi i32 [ %call, %cond.true ], [ %call1, %cond.false ] ret i32 %cond } @@ -124,23 +156,32 @@ cond.end: ; preds = %cond.false, %cond.t ; TEST 3: both cond.true and cond.false are dead, therfore cond.end is dead as well. define i32 @all_dead(i32 %a) #0 { +; CHECK-LABEL: define {{[^@]+}}@all_dead +; CHECK-SAME: (i32 [[A:%.*]]) +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A]], 0 +; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +; CHECK: cond.true: +; CHECK-NEXT: call void @no_return_call() +; CHECK-NEXT: unreachable +; CHECK: cond.false: +; CHECK-NEXT: call void @no_return_call() +; CHECK-NEXT: unreachable +; CHECK: cond.end: +; CHECK-NEXT: unreachable +; entry: %cmp = icmp eq i32 %a, 0 br i1 %cmp, label %cond.true, label %cond.false cond.true: ; preds = %entry call void @no_return_call() - ; CHECK: call void @no_return_call() - ; CHECK-NEXT: unreachable call i32 @dead_internal_func(i32 10) - ; CHECK-NOT: call %call = call i32 @foo() br label %cond.end cond.false: ; preds = %entry call void @no_return_call() - ; CHECK: call void @no_return_call() - ; CHECK-NEXT: unreachable call i32 @dead_internal_func(i32 10) %call1 = call i32 @bar() br label %cond.end @@ -154,8 +195,23 @@ declare i32 @__gxx_personality_v0(...) ; TEST 4: All blocks are live. -; CHECK: define i32 @all_live(i32 %a) define i32 @all_live(i32 %a) #0 { +; CHECK-LABEL: define {{[^@]+}}@all_live +; CHECK-SAME: (i32 [[A:%.*]]) +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A]], 0 +; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +; CHECK: cond.true: +; CHECK-NEXT: call void @normal_call() +; CHECK-NEXT: [[CALL:%.*]] = call i32 @foo_noreturn() +; CHECK-NEXT: unreachable +; CHECK: cond.false: +; CHECK-NEXT: call void @normal_call() +; CHECK-NEXT: [[CALL1:%.*]] = call i32 @bar() +; CHECK-NEXT: br label [[COND_END:%.*]] +; CHECK: cond.end: +; CHECK-NEXT: ret i32 [[CALL1]] +; entry: %cmp = icmp eq i32 %a, 0 br i1 %cmp, label %cond.true, label %cond.false @@ -177,8 +233,29 @@ cond.end: ; preds = %cond.false, %cond.t ; TEST 5.1 noreturn invoke instruction with a unreachable normal successor block. -; CHECK: define i32 @invoke_noreturn(i32 %a) define i32 @invoke_noreturn(i32 %a) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { +; CHECK-LABEL: define {{[^@]+}}@invoke_noreturn +; CHECK-SAME: (i32 [[A:%.*]]) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A]], 0 +; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +; CHECK: cond.true: +; CHECK-NEXT: call void @normal_call() +; CHECK-NEXT: [[CALL:%.*]] = invoke i32 @foo_noreturn() +; CHECK-NEXT: to label [[CONTINUE:%.*]] unwind label [[CLEANUP:%.*]] +; CHECK: cond.false: +; CHECK-NEXT: call void @normal_call() +; CHECK-NEXT: [[CALL1:%.*]] = call i32 @bar() +; CHECK-NEXT: br label [[COND_END:%.*]] +; CHECK: cond.end: +; CHECK-NEXT: ret i32 [[CALL1]] +; CHECK: continue: +; CHECK-NEXT: unreachable +; CHECK: cleanup: +; CHECK-NEXT: [[RES:%.*]] = landingpad { i8*, i32 } +; CHECK-NEXT: catch i8* null +; CHECK-NEXT: ret i32 0 +; entry: %cmp = icmp eq i32 %a, 0 br i1 %cmp, label %cond.true, label %cond.false @@ -186,9 +263,7 @@ entry: cond.true: ; preds = %entry call void @normal_call() %call = invoke i32 @foo_noreturn() to label %continue - unwind label %cleanup - ; CHECK: %call = invoke i32 @foo_noreturn() - ; CHECK-NEXT: to label %continue unwind label %cleanup + unwind label %cleanup cond.false: ; preds = %entry call void @normal_call() @@ -200,8 +275,6 @@ cond.end: ; preds = %cond.false, %contin ret i32 %cond continue: - ; CHECK: continue: - ; CHECK-NEXT: unreachable br label %cond.end cleanup: @@ -213,8 +286,27 @@ cleanup: ; TEST 5.2 noreturn invoke instruction replaced by a call and an unreachable instruction ; put after it. -; CHECK: define i32 @invoke_noreturn_nounwind(i32 %a) define i32 @invoke_noreturn_nounwind(i32 %a) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { +; CHECK-LABEL: define {{[^@]+}}@invoke_noreturn_nounwind +; CHECK-SAME: (i32 [[A:%.*]]) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A]], 0 +; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +; CHECK: cond.true: +; CHECK-NEXT: call void @normal_call() +; CHECK-NEXT: [[CALL:%.*]] = call i32 @foo_noreturn_nounwind() +; CHECK-NEXT: unreachable +; CHECK: cond.false: +; CHECK-NEXT: call void @normal_call() +; CHECK-NEXT: [[CALL1:%.*]] = call i32 @bar() +; CHECK-NEXT: br label [[COND_END:%.*]] +; CHECK: cond.end: +; CHECK-NEXT: ret i32 [[CALL1]] +; CHECK: continue: +; CHECK-NEXT: unreachable +; CHECK: cleanup: +; CHECK-NEXT: unreachable +; entry: %cmp = icmp eq i32 %a, 0 br i1 %cmp, label %cond.true, label %cond.false @@ -222,12 +314,8 @@ entry: cond.true: ; preds = %entry call void @normal_call() %call = invoke i32 @foo_noreturn_nounwind() to label %continue - unwind label %cleanup - ; CHECK: call void @normal_call() - ; CHECK-NEXT: call i32 @foo_noreturn_nounwind() - ; CHECK-NEXT: unreachable + unwind label %cleanup - ; CHECK-NOT: @foo_noreturn_nounwind() cond.false: ; preds = %entry call void @normal_call() @@ -250,12 +338,25 @@ cleanup: ; TEST 5.3 unounwind invoke instruction replaced by a call and a branch instruction put after it. define i32 @invoke_nounwind(i32 %a) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { ; CHECK-LABEL: define {{[^@]+}}@invoke_nounwind +; CHECK-SAME: (i32 [[A:%.*]]) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A]], 0 +; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] ; CHECK: cond.true: ; CHECK-NEXT: call void @normal_call() ; CHECK-NEXT: [[CALL:%.*]] = call i32 @foo_nounwind() ; CHECK-NEXT: br label [[CONTINUE:%.*]] -; CHECK: continue: +; CHECK: cond.false: +; CHECK-NEXT: call void @normal_call() +; CHECK-NEXT: [[CALL1:%.*]] = call i32 @bar() ; CHECK-NEXT: br label [[COND_END:%.*]] +; CHECK: cond.end: +; CHECK-NEXT: [[COND:%.*]] = phi i32 [ [[CALL]], [[CONTINUE]] ], [ [[CALL1]], [[COND_FALSE]] ] +; CHECK-NEXT: ret i32 [[COND]] +; CHECK: continue: +; CHECK-NEXT: br label [[COND_END]] +; CHECK: cleanup: +; CHECK-NEXT: unreachable ; entry: %cmp = icmp eq i32 %a, 0 @@ -284,8 +385,6 @@ cleanup: ret i32 0 } -; UTC_ARGS: --enable - ; TEST 5.4 unounwind invoke instruction replaced by a call and a branch instruction put after it. define i32 @invoke_nounwind_phi(i32 %a) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { ; CHECK-LABEL: define {{[^@]+}}@invoke_nounwind_phi @@ -374,13 +473,18 @@ cleanup: ret i32 0 } -; UTC_ARGS: --disable - ; TEST 6: Undefined behvior, taken from LangRef. ; FIXME: Should be able to detect undefined behavior. -; CHECK: define void @ub(i32* nocapture nofree writeonly %0) define void @ub(i32* %0) { +; CHECK-LABEL: define {{[^@]+}}@ub +; CHECK-SAME: (i32* nocapture nofree writeonly [[TMP0:%.*]]) +; CHECK-NEXT: [[POISON:%.*]] = sub nuw i32 0, 1 +; CHECK-NEXT: [[STILL_POISON:%.*]] = and i32 [[POISON]], 0 +; CHECK-NEXT: [[POISON_YET_AGAIN:%.*]] = getelementptr i32, i32* [[TMP0]], i32 [[STILL_POISON]] +; CHECK-NEXT: store i32 0, i32* [[POISON_YET_AGAIN]], align 4 +; CHECK-NEXT: ret void +; %poison = sub nuw i32 0, 1 ; Results in a poison value. %still_poison = and i32 %poison, 0 ; 0, but also poison. %poison_yet_again = getelementptr i32, i32* %0, i32 %still_poison @@ -389,6 +493,12 @@ define void @ub(i32* %0) { } define void @inf_loop() #0 { +; CHECK-LABEL: define {{[^@]+}}@inf_loop() +; CHECK-NEXT: entry: +; CHECK-NEXT: br label [[WHILE_BODY:%.*]] +; CHECK: while.body: +; CHECK-NEXT: br label [[WHILE_BODY]] +; entry: br label %while.body @@ -400,6 +510,20 @@ while.body: ; preds = %entry, %while.body ; FIXME: Detect infloops, and mark affected blocks dead. define i32 @test5(i32, i32) #0 { +; CHECK-LABEL: define {{[^@]+}}@test5 +; CHECK-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]]) +; CHECK-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP0]], [[TMP1]] +; CHECK-NEXT: br i1 [[TMP3]], label [[COND_IF:%.*]], label [[COND_ELSEIF:%.*]] +; CHECK: cond.if: +; CHECK-NEXT: [[TMP4:%.*]] = tail call i32 @bar() +; CHECK-NEXT: br label [[COND_END:%.*]] +; CHECK: cond.elseif: +; CHECK-NEXT: unreachable +; CHECK: cond.else: +; CHECK-NEXT: unreachable +; CHECK: cond.end: +; CHECK-NEXT: ret i32 0 +; %3 = icmp sgt i32 %0, %1 br i1 %3, label %cond.if, label %cond.elseif @@ -422,6 +546,10 @@ cond.end: ; preds = %cond.if, %con } define void @rec() #0 { +; CHECK-LABEL: define {{[^@]+}}@rec() +; CHECK-NEXT: entry: +; CHECK-NEXT: unreachable +; entry: call void @rec() ret void @@ -432,6 +560,18 @@ entry: ; and unreachable should be put after call to @rec(). define i32 @test6(i32, i32) #0 { +; CHECK-LABEL: define {{[^@]+}}@test6 +; CHECK-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]]) +; CHECK-NEXT: unreachable +; CHECK: cond.if: +; CHECK-NEXT: unreachable +; CHECK: cond.elseif: +; CHECK-NEXT: unreachable +; CHECK: cond.else: +; CHECK-NEXT: unreachable +; CHECK: cond.end: +; CHECK-NEXT: unreachable +; call void @rec() %3 = icmp sgt i32 %0, %1 br i1 %3, label %cond.if, label %cond.elseif @@ -457,6 +597,24 @@ cond.end: ; preds = %cond.if, %con ; FIXME: contains recursive call to itself in cond.elseif block define i32 @test7(i32, i32) #0 { +; CHECK-LABEL: define {{[^@]+}}@test7 +; CHECK-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]]) +; CHECK-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP0]], [[TMP1]] +; CHECK-NEXT: br i1 [[TMP3]], label [[COND_IF:%.*]], label [[COND_ELSEIF:%.*]] +; CHECK: cond.if: +; CHECK-NEXT: [[TMP4:%.*]] = tail call i32 @bar() +; CHECK-NEXT: br label [[COND_END:%.*]] +; CHECK: cond.elseif: +; CHECK-NEXT: [[TMP5:%.*]] = tail call i32 @test7(i32 [[TMP0]], i32 [[TMP1]]) +; CHECK-NEXT: [[TMP6:%.*]] = icmp slt i32 [[TMP0]], [[TMP1]] +; CHECK-NEXT: br i1 [[TMP6]], label [[COND_END]], label [[COND_ELSE:%.*]] +; CHECK: cond.else: +; CHECK-NEXT: [[TMP7:%.*]] = tail call i32 @foo() +; CHECK-NEXT: br label [[COND_END]] +; CHECK: cond.end: +; CHECK-NEXT: [[TMP8:%.*]] = phi i32 [ [[TMP1]], [[COND_ELSEIF]] ], [ 0, [[COND_ELSE]] ], [ 0, [[COND_IF]] ] +; CHECK-NEXT: ret i32 [[TMP8]] +; %3 = icmp sgt i32 %0, %1 br i1 %3, label %cond.if, label %cond.elseif @@ -498,12 +656,21 @@ cond.end: ; preds = %cond.if, %con @a2 = common global i8 0, align 16 define internal i8* @f1(i8* readnone %0) local_unnamed_addr #0 { -; ATTRIBUTOR: define internal i8* @f1(i8* readnone %0) +; CHECK-LABEL: define {{[^@]+}}@f1 +; CHECK-SAME: (i8* readnone [[TMP0:%.*]]) local_unnamed_addr +; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8* [[TMP0]], null +; CHECK-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP5:%.*]] +; CHECK: 3: +; CHECK-NEXT: [[TMP4:%.*]] = tail call i8* @f2(i8* nonnull @a1) +; CHECK-NEXT: br label [[TMP5]] +; CHECK: 5: +; CHECK-NEXT: [[TMP6:%.*]] = phi i8* [ [[TMP4]], [[TMP3]] ], [ [[TMP0]], [[TMP1:%.*]] ] +; CHECK-NEXT: ret i8* [[TMP6]] +; %2 = icmp eq i8* %0, null br i1 %2, label %3, label %5 ;