diff --git a/llvm/include/llvm/Transforms/IPO/Attributor.h b/llvm/include/llvm/Transforms/IPO/Attributor.h --- a/llvm/include/llvm/Transforms/IPO/Attributor.h +++ b/llvm/include/llvm/Transforms/IPO/Attributor.h @@ -147,6 +147,17 @@ /// how to cast various constants. Value *getWithType(Value &V, Type &Ty); +/// Return the combination of \p A and \p B such that the result is a possible +/// value of both. \p B is potentially casted to match the type \p Ty or the +/// type of \p A if \p Ty is null. +/// +/// Examples: +/// X + none => X +/// not_none + undef => not_none +/// V1 + V2 => nullptr +Optional +combineOptionalValuesInAAValueLatice(const Optional &A, + const Optional &B, Type *Ty); } // namespace AA /// The value passed to the line option that defines the maximal initialization diff --git a/llvm/lib/Transforms/IPO/Attributor.cpp b/llvm/lib/Transforms/IPO/Attributor.cpp --- a/llvm/lib/Transforms/IPO/Attributor.cpp +++ b/llvm/lib/Transforms/IPO/Attributor.cpp @@ -195,6 +195,30 @@ return nullptr; } +Optional +AA::combineOptionalValuesInAAValueLatice(const Optional &A, + const Optional &B, Type *Ty) { + if (A == B) + return A; + if (!B.hasValue()) + return A; + if (*B == nullptr) + return nullptr; + if (!A.hasValue()) + return Ty ? getWithType(**B, *Ty) : nullptr; + if (*A == nullptr) + return nullptr; + if (!Ty) + Ty = (*A)->getType(); + if (isa_and_nonnull(*A)) + return getWithType(**B, *Ty); + if (isa(*B)) + return A; + if (*A && *B && *A == getWithType(**B, *Ty)) + return A; + return nullptr; +} + /// Return true if \p New is equal or worse than \p Old. static bool isEqualOrWorse(const Attribute &New, const Attribute &Old) { if (!Old.isIntAttribute()) diff --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp --- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp +++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp @@ -1002,22 +1002,11 @@ // multiple, a nullptr is returned indicating there cannot be a unique // returned value. Optional UniqueRV; + Type *Ty = getAssociatedFunction()->getReturnType(); auto Pred = [&](Value &RV) -> bool { - // If we found a second returned value and neither the current nor the saved - // one is an undef, there is no unique returned value. Undefs are special - // since we can pretend they have any value. - if (UniqueRV.hasValue() && UniqueRV != &RV && - !(isa(RV) || isa(UniqueRV.getValue()))) { - UniqueRV = nullptr; - return false; - } - - // Do not overwrite a value with an undef. - if (!UniqueRV.hasValue() || !isa(RV)) - UniqueRV = &RV; - - return true; + UniqueRV = AA::combineOptionalValuesInAAValueLatice(UniqueRV, &RV, Ty); + return UniqueRV != Optional(nullptr); }; if (!A.checkForAllReturnedValues(Pred, *this)) @@ -4515,26 +4504,18 @@ bool ValueSimplifyStateType::unionAssumed(Optional Other) { // FIXME: Add a typecast support. - if (!Other.hasValue()) - return true; - - if (!Other.getValue()) + SimplifiedAssociatedValue = AA::combineOptionalValuesInAAValueLatice( + SimplifiedAssociatedValue, Other, Ty); + if (SimplifiedAssociatedValue == Optional(nullptr)) return false; - Value &QueryingValueSimplifiedUnwrapped = *Other.getValue(); - - if (SimplifiedAssociatedValue.hasValue() && - !isa(SimplifiedAssociatedValue.getValue()) && - !isa(QueryingValueSimplifiedUnwrapped)) - return SimplifiedAssociatedValue == Other; - if (SimplifiedAssociatedValue.hasValue() && - isa(QueryingValueSimplifiedUnwrapped)) - return true; - - LLVM_DEBUG(dbgs() << "[ValueSimplify] is assumed to be " - << QueryingValueSimplifiedUnwrapped << "\n"); - - SimplifiedAssociatedValue = Other; + LLVM_DEBUG({ + if (SimplifiedAssociatedValue.hasValue()) + dbgs() << "[ValueSimplify] is assumed to be " + << **SimplifiedAssociatedValue << "\n"; + else + dbgs() << "[ValueSimplify] is assumed to be \n"; + }); return true; } diff --git a/llvm/test/Transforms/Attributor/dereferenceable-1.ll b/llvm/test/Transforms/Attributor/dereferenceable-1.ll --- a/llvm/test/Transforms/Attributor/dereferenceable-1.ll +++ b/llvm/test/Transforms/Attributor/dereferenceable-1.ll @@ -1,6 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals -; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -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-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 -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=17 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM +; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=17 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM ; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM ; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM ; FIXME: Figure out why we need 16 iterations here. diff --git a/llvm/test/Transforms/Attributor/liveness.ll b/llvm/test/Transforms/Attributor/liveness.ll --- a/llvm/test/Transforms/Attributor/liveness.ll +++ b/llvm/test/Transforms/Attributor/liveness.ll @@ -1,6 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals -; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=35 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM -; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=35 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM +; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=37 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM +; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=37 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM ; TODO: The old pass manager cgscc run is disabled as it causes a crash on windows which is under investigation: http://lab.llvm.org:8011/builders/llvm-clang-x86_64-expensive-checks-win/builds/23151 ; opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM ; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM diff --git a/llvm/test/Transforms/Attributor/lvi-after-jumpthreading.ll b/llvm/test/Transforms/Attributor/lvi-after-jumpthreading.ll --- a/llvm/test/Transforms/Attributor/lvi-after-jumpthreading.ll +++ b/llvm/test/Transforms/Attributor/lvi-after-jumpthreading.ll @@ -1,6 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals -; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -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-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 -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=18 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM +; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=18 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM ; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM ; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM diff --git a/llvm/test/Transforms/Attributor/nocapture-2.ll b/llvm/test/Transforms/Attributor/nocapture-2.ll --- a/llvm/test/Transforms/Attributor/nocapture-2.ll +++ b/llvm/test/Transforms/Attributor/nocapture-2.ll @@ -211,7 +211,7 @@ define float* @scc_A(i32* dereferenceable_or_null(4) %a) { ; CHECK: Function Attrs: nofree nosync nounwind readnone ; CHECK-LABEL: define {{[^@]+}}@scc_A -; CHECK-SAME: (i32* nofree readnone returned dereferenceable_or_null(4) "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR2:[0-9]+]] { +; CHECK-SAME: (i32* nofree readnone dereferenceable_or_null(4) "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR2:[0-9]+]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32* [[A]], null ; CHECK-NEXT: br i1 [[TOBOOL]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] @@ -257,7 +257,7 @@ define i64* @scc_B(double* dereferenceable_or_null(8) %a) { ; CHECK: Function Attrs: nofree nosync nounwind readnone ; CHECK-LABEL: define {{[^@]+}}@scc_B -; CHECK-SAME: (double* nofree readnone returned dereferenceable_or_null(8) "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR2]] { +; CHECK-SAME: (double* nofree readnone dereferenceable_or_null(8) "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR2]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne double* [[A]], null ; CHECK-NEXT: br i1 [[TOBOOL]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] @@ -303,7 +303,7 @@ define i8* @scc_C(i16* dereferenceable_or_null(2) %a) { ; CHECK: Function Attrs: nofree nosync nounwind readnone ; CHECK-LABEL: define {{[^@]+}}@scc_C -; CHECK-SAME: (i16* nofree readnone returned dereferenceable_or_null(4) "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR2]] { +; CHECK-SAME: (i16* nofree readnone dereferenceable_or_null(4) "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR2]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[BC:%.*]] = bitcast i16* [[A]] to i32* ; CHECK-NEXT: [[CALL:%.*]] = call dereferenceable_or_null(4) float* @scc_A(i32* noalias nofree readnone dereferenceable_or_null(4) "no-capture-maybe-returned" [[BC]]) #[[ATTR2]] diff --git a/llvm/test/Transforms/Attributor/nonnull.ll b/llvm/test/Transforms/Attributor/nonnull.ll --- a/llvm/test/Transforms/Attributor/nonnull.ll +++ b/llvm/test/Transforms/Attributor/nonnull.ll @@ -1671,14 +1671,12 @@ ; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@nonnull_function_ptr_1 ; IS__TUNIT____-SAME: () #[[ATTR1]] { -; IS__TUNIT____-NEXT: [[BC:%.*]] = bitcast i8* ()* @nonnull_function_ptr_1 to i8* -; IS__TUNIT____-NEXT: ret i8* [[BC]] +; IS__TUNIT____-NEXT: ret i8* bitcast (i8* ()* @nonnull_function_ptr_1 to i8*) ; ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@nonnull_function_ptr_1 ; IS__CGSCC____-SAME: () #[[ATTR1]] { -; IS__CGSCC____-NEXT: [[BC:%.*]] = bitcast i8* ()* @nonnull_function_ptr_1 to i8* -; IS__CGSCC____-NEXT: ret i8* [[BC]] +; IS__CGSCC____-NEXT: ret i8* bitcast (i8* ()* @nonnull_function_ptr_1 to i8*) ; %bc = bitcast i8*()* @nonnull_function_ptr_1 to i8* ret i8* %bc @@ -1689,14 +1687,12 @@ ; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@nonnull_function_ptr_2 ; IS__TUNIT____-SAME: () #[[ATTR1]] { -; IS__TUNIT____-NEXT: [[BC:%.*]] = bitcast i8* ()* @function_decl to i8* -; IS__TUNIT____-NEXT: ret i8* [[BC]] +; IS__TUNIT____-NEXT: ret i8* bitcast (i8* ()* @function_decl to i8*) ; ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@nonnull_function_ptr_2 ; IS__CGSCC____-SAME: () #[[ATTR1]] { -; IS__CGSCC____-NEXT: [[BC:%.*]] = bitcast i8* ()* @function_decl to i8* -; IS__CGSCC____-NEXT: ret i8* [[BC]] +; IS__CGSCC____-NEXT: ret i8* bitcast (i8* ()* @function_decl to i8*) ; %bc = bitcast i8*()* @function_decl to i8* ret i8* %bc diff --git a/llvm/test/Transforms/Attributor/potential.ll b/llvm/test/Transforms/Attributor/potential.ll --- a/llvm/test/Transforms/Attributor/potential.ll +++ b/llvm/test/Transforms/Attributor/potential.ll @@ -1,6 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals -; RUN: opt -enable-new-pm=0 -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=22 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM -; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=22 -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 -enable-new-pm=0 -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=24 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM +; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=24 -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 -enable-new-pm=0 -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM ; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM ; diff --git a/llvm/test/Transforms/Attributor/range.ll b/llvm/test/Transforms/Attributor/range.ll --- a/llvm/test/Transforms/Attributor/range.ll +++ b/llvm/test/Transforms/Attributor/range.ll @@ -1,6 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals -; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=24 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM -; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=24 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM +; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=25 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM +; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=26 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM ; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM ; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM diff --git a/llvm/test/Transforms/Attributor/returned.ll b/llvm/test/Transforms/Attributor/returned.ll --- a/llvm/test/Transforms/Attributor/returned.ll +++ b/llvm/test/Transforms/Attributor/returned.ll @@ -917,14 +917,14 @@ define double* @bitcast(i32* %b) #0 { ; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@bitcast -; IS__TUNIT____-SAME: (i32* nofree readnone returned "no-capture-maybe-returned" [[B:%.*]]) #[[ATTR0]] { +; IS__TUNIT____-SAME: (i32* nofree readnone "no-capture-maybe-returned" [[B:%.*]]) #[[ATTR0]] { ; IS__TUNIT____-NEXT: entry: ; IS__TUNIT____-NEXT: [[BC0:%.*]] = bitcast i32* [[B]] to double* ; IS__TUNIT____-NEXT: ret double* [[BC0]] ; ; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@bitcast -; IS__CGSCC____-SAME: (i32* nofree readnone returned "no-capture-maybe-returned" [[B:%.*]]) #[[ATTR0]] { +; IS__CGSCC____-SAME: (i32* nofree readnone "no-capture-maybe-returned" [[B:%.*]]) #[[ATTR0]] { ; IS__CGSCC____-NEXT: entry: ; IS__CGSCC____-NEXT: [[BC0:%.*]] = bitcast i32* [[B]] to double* ; IS__CGSCC____-NEXT: ret double* [[BC0]] @@ -947,7 +947,7 @@ define double* @bitcasts_select_and_phi(i32* %b) #0 { ; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@bitcasts_select_and_phi -; IS__TUNIT____-SAME: (i32* nofree readnone returned [[B:%.*]]) #[[ATTR0]] { +; IS__TUNIT____-SAME: (i32* nofree readnone [[B:%.*]]) #[[ATTR0]] { ; IS__TUNIT____-NEXT: entry: ; IS__TUNIT____-NEXT: [[BC0:%.*]] = bitcast i32* [[B]] to double* ; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp eq double* [[BC0]], null @@ -966,7 +966,7 @@ ; ; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@bitcasts_select_and_phi -; IS__CGSCC____-SAME: (i32* nofree readnone returned [[B:%.*]]) #[[ATTR0]] { +; IS__CGSCC____-SAME: (i32* nofree readnone [[B:%.*]]) #[[ATTR0]] { ; IS__CGSCC____-NEXT: entry: ; IS__CGSCC____-NEXT: [[BC0:%.*]] = bitcast i32* [[B]] to double* ; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp eq double* [[BC0]], null @@ -1016,7 +1016,7 @@ define double* @ret_arg_arg_undef(i32* %b) #0 { ; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@ret_arg_arg_undef -; IS__TUNIT____-SAME: (i32* nofree readnone returned [[B:%.*]]) #[[ATTR0]] { +; IS__TUNIT____-SAME: (i32* nofree readnone [[B:%.*]]) #[[ATTR0]] { ; IS__TUNIT____-NEXT: entry: ; IS__TUNIT____-NEXT: [[BC0:%.*]] = bitcast i32* [[B]] to double* ; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp eq double* [[BC0]], null @@ -1033,7 +1033,7 @@ ; ; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@ret_arg_arg_undef -; IS__CGSCC____-SAME: (i32* nofree readnone returned [[B:%.*]]) #[[ATTR0]] { +; IS__CGSCC____-SAME: (i32* nofree readnone [[B:%.*]]) #[[ATTR0]] { ; IS__CGSCC____-NEXT: entry: ; IS__CGSCC____-NEXT: [[BC0:%.*]] = bitcast i32* [[B]] to double* ; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp eq double* [[BC0]], null @@ -1081,7 +1081,7 @@ define double* @ret_undef_arg_arg(i32* %b) #0 { ; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@ret_undef_arg_arg -; IS__TUNIT____-SAME: (i32* nofree readnone returned [[B:%.*]]) #[[ATTR0]] { +; IS__TUNIT____-SAME: (i32* nofree readnone [[B:%.*]]) #[[ATTR0]] { ; IS__TUNIT____-NEXT: entry: ; IS__TUNIT____-NEXT: [[BC0:%.*]] = bitcast i32* [[B]] to double* ; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp eq double* [[BC0]], null @@ -1098,7 +1098,7 @@ ; ; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@ret_undef_arg_arg -; IS__CGSCC____-SAME: (i32* nofree readnone returned [[B:%.*]]) #[[ATTR0]] { +; IS__CGSCC____-SAME: (i32* nofree readnone [[B:%.*]]) #[[ATTR0]] { ; IS__CGSCC____-NEXT: entry: ; IS__CGSCC____-NEXT: [[BC0:%.*]] = bitcast i32* [[B]] to double* ; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp eq double* [[BC0]], null @@ -1146,7 +1146,7 @@ define double* @ret_undef_arg_undef(i32* %b) #0 { ; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@ret_undef_arg_undef -; IS__TUNIT____-SAME: (i32* nofree readnone returned [[B:%.*]]) #[[ATTR0]] { +; IS__TUNIT____-SAME: (i32* nofree readnone [[B:%.*]]) #[[ATTR0]] { ; IS__TUNIT____-NEXT: entry: ; IS__TUNIT____-NEXT: [[BC0:%.*]] = bitcast i32* [[B]] to double* ; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp eq double* [[BC0]], null @@ -1162,7 +1162,7 @@ ; ; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@ret_undef_arg_undef -; IS__CGSCC____-SAME: (i32* nofree readnone returned [[B:%.*]]) #[[ATTR0]] { +; IS__CGSCC____-SAME: (i32* nofree readnone [[B:%.*]]) #[[ATTR0]] { ; IS__CGSCC____-NEXT: entry: ; IS__CGSCC____-NEXT: [[BC0:%.*]] = bitcast i32* [[B]] to double* ; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp eq double* [[BC0]], null @@ -1513,14 +1513,12 @@ ; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@ret_const ; IS__TUNIT____-SAME: () #[[ATTR0]] { -; IS__TUNIT____-NEXT: [[BC:%.*]] = bitcast i8* @G to i32* -; IS__TUNIT____-NEXT: ret i32* [[BC]] +; IS__TUNIT____-NEXT: ret i32* bitcast (i8* @G to i32*) ; ; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@ret_const ; IS__CGSCC____-SAME: () #[[ATTR0]] { -; IS__CGSCC____-NEXT: [[BC:%.*]] = bitcast i8* @G to i32* -; IS__CGSCC____-NEXT: ret i32* [[BC]] +; IS__CGSCC____-NEXT: ret i32* bitcast (i8* @G to i32*) ; %bc = bitcast i8* @G to i32* ret i32* %bc @@ -1543,14 +1541,12 @@ ; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@dont_use_const ; IS__TUNIT____-SAME: () #[[ATTR0]] { -; IS__TUNIT____-NEXT: [[C:%.*]] = musttail call i32* @ret_const() #[[ATTR5]] -; IS__TUNIT____-NEXT: ret i32* [[C]] +; IS__TUNIT____-NEXT: ret i32* bitcast (i8* @G to i32*) ; ; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@dont_use_const ; IS__CGSCC____-SAME: () #[[ATTR0]] { -; IS__CGSCC____-NEXT: [[C:%.*]] = musttail call i32* @ret_const() #[[ATTR6]] -; IS__CGSCC____-NEXT: ret i32* [[C]] +; IS__CGSCC____-NEXT: ret i32* bitcast (i8* @G to i32*) ; %c = musttail call i32* @ret_const() ret i32* %c diff --git a/llvm/test/Transforms/Attributor/value-simplify.ll b/llvm/test/Transforms/Attributor/value-simplify.ll --- a/llvm/test/Transforms/Attributor/value-simplify.ll +++ b/llvm/test/Transforms/Attributor/value-simplify.ll @@ -1,6 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals -; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -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-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 -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=17 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM +; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=17 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM ; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM ; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM @@ -1228,6 +1228,32 @@ ; }}} + +define i1 @test_cmp_null_after_cast() { +; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@test_cmp_null_after_cast +; IS__TUNIT____-SAME: () #[[ATTR1]] { +; IS__TUNIT____-NEXT: ret i1 true +; +; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@test_cmp_null_after_cast +; IS__CGSCC____-SAME: () #[[ATTR1]] { +; IS__CGSCC____-NEXT: ret i1 true +; + %c = call i1 @cmp_null_after_cast(i32 0, i8 0) + ret i1 %c +} +define internal i1 @cmp_null_after_cast(i32 %a, i8 %b) { +; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@cmp_null_after_cast +; IS__CGSCC____-SAME: () #[[ATTR1]] { +; IS__CGSCC____-NEXT: ret i1 undef +; + %t = trunc i32 %a to i8 + %c = icmp eq i8 %t, %b + ret i1 %c +} + ;. ; IS__TUNIT_OPM: attributes #[[ATTR0]] = { nofree nosync nounwind willreturn } ; IS__TUNIT_OPM: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn }