[llvm] 0636c93 - [Attributor] Remove restriction on simplifying function pointers

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 7 02:54:58 PST 2022


Author: Nikita Popov
Date: 2022-03-07T11:54:37+01:00
New Revision: 0636c93d3e43220f6513447cf8158e69cc1953c5

URL: https://github.com/llvm/llvm-project/commit/0636c93d3e43220f6513447cf8158e69cc1953c5
DIFF: https://github.com/llvm/llvm-project/commit/0636c93d3e43220f6513447cf8158e69cc1953c5.diff

LOG: [Attributor] Remove restriction on simplifying function pointers

Dropping this restriction seems to work fine (there are no assertion
failures), so it appears that either the updater got smarter or the
problematic cases are restricted elsewhere.

If doing this still causes issues, then the place to address it
would probably be https://github.com/llvm/llvm-project/blob/8f5bdaf481c3f4e6876a5ae0e4d7c6ed2042e6a6/llvm/lib/Transforms/IPO/Attributor.cpp#L1856-L1859,
which already prevents replacement outside the SCC, so I'm not
quite sure what this check is intended to avoid.

Differential Revision: https://reviews.llvm.org/D120987

Added: 
    

Modified: 
    llvm/lib/Transforms/IPO/AttributorAttributes.cpp
    llvm/test/Transforms/Attributor/liveness.ll
    llvm/test/Transforms/Attributor/value-simplify.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
index 2b616ae77884e..73f6d1cfeda51 100644
--- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
+++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
@@ -5501,15 +5501,6 @@ struct AAValueSimplifyArgument final : AAValueSimplifyImpl {
                  Attribute::StructRet, Attribute::Nest, Attribute::ByVal},
                 /* IgnoreSubsumingPositions */ true))
       indicatePessimisticFixpoint();
-
-    // FIXME: This is a hack to prevent us from propagating function poiner in
-    // the new pass manager CGSCC pass as it creates call edges the
-    // CallGraphUpdater cannot handle yet.
-    Value &V = getAssociatedValue();
-    if (V.getType()->isPointerTy() &&
-        V.getType()->getPointerElementType()->isFunctionTy() &&
-        !A.isModulePass())
-      indicatePessimisticFixpoint();
   }
 
   /// See AbstractAttribute::updateImpl(...).

diff  --git a/llvm/test/Transforms/Attributor/liveness.ll b/llvm/test/Transforms/Attributor/liveness.ll
index 41779e54dad37..483fa0c88ebd8 100644
--- a/llvm/test/Transforms/Attributor/liveness.ll
+++ b/llvm/test/Transforms/Attributor/liveness.ll
@@ -2281,7 +2281,7 @@ define void @call_via_pointer_with_dead_args(i32* %a, i32* %b, void (i32*, i32*,
   call void %fp(i32* %a, i32* %b, i32* %a, i64 -1, i32** null)
   ret void
 }
-; FIXME: We have to prevent the propagation of %fp in the new pm CGSCC pass until the CallGraphUpdater can handle the new call edge.
+
 define internal void @call_via_pointer_with_dead_args_internal_a(i32* %a, i32* %b, void (i32*, i32*, i32*, i64, i32**)* %fp) {
 ; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@call_via_pointer_with_dead_args_internal_a
 ; NOT_CGSCC_NPM-SAME: (i32* [[A:%.*]], i32* noundef nonnull align 128 dereferenceable(4) [[B:%.*]]) {
@@ -2289,8 +2289,8 @@ define internal void @call_via_pointer_with_dead_args_internal_a(i32* %a, i32* %
 ; NOT_CGSCC_NPM-NEXT:    ret void
 ;
 ; IS__CGSCC____-LABEL: define {{[^@]+}}@call_via_pointer_with_dead_args_internal_a
-; IS__CGSCC____-SAME: (i32* [[A:%.*]], i32* noundef nonnull align 128 dereferenceable(4) [[B:%.*]], void (i32*, i32*, i32*, i64, i32**)* nocapture nofree noundef nonnull [[FP:%.*]]) {
-; IS__CGSCC____-NEXT:    call void [[FP]](i32* [[A]], i32* nonnull align 128 dereferenceable(4) [[B]], i32* [[A]], i64 -1, i32** null)
+; IS__CGSCC____-SAME: (i32* [[A:%.*]], i32* noalias nocapture nofree nonnull readnone align 128 dereferenceable(4) [[B:%.*]]) {
+; IS__CGSCC____-NEXT:    call void @called_via_pointer(i32* [[A]], i32* noalias nocapture nofree nonnull readnone align 128 dereferenceable(4) undef, i32* noalias nocapture nofree readnone undef, i64 undef, i32** noalias nocapture nofree readnone align 4294967296 undef)
 ; IS__CGSCC____-NEXT:    ret void
 ;
   call void %fp(i32* %a, i32* %b, i32* %a, i64 -1, i32** null)
@@ -2303,8 +2303,8 @@ define internal void @call_via_pointer_with_dead_args_internal_b(i32* %a, i32* %
 ; NOT_CGSCC_NPM-NEXT:    ret void
 ;
 ; IS__CGSCC____-LABEL: define {{[^@]+}}@call_via_pointer_with_dead_args_internal_b
-; IS__CGSCC____-SAME: (i32* [[A:%.*]], i32* noundef nonnull align 128 dereferenceable(4) [[B:%.*]], void (i32*, i32*, i32*, i64, i32**)* nocapture nofree noundef nonnull [[FP:%.*]]) {
-; IS__CGSCC____-NEXT:    call void [[FP]](i32* [[A]], i32* nonnull align 128 dereferenceable(4) [[B]], i32* [[A]], i64 -1, i32** null)
+; IS__CGSCC____-SAME: (i32* [[A:%.*]], i32* noalias nocapture nofree nonnull readnone align 128 dereferenceable(4) [[B:%.*]]) {
+; IS__CGSCC____-NEXT:    call void @called_via_pointer_internal_2(i32* [[A]])
 ; IS__CGSCC____-NEXT:    ret void
 ;
   call void %fp(i32* %a, i32* %b, i32* %a, i64 -1, i32** null)
@@ -2327,12 +2327,10 @@ define void @call_via_pointer_with_dead_args_caller(i32* %a, i32* %b) {
 ; IS__CGSCC____-SAME: (i32* [[A:%.*]], i32* [[B:%.*]]) {
 ; IS__CGSCC____-NEXT:    [[PTR1:%.*]] = alloca i32, align 128
 ; IS__CGSCC____-NEXT:    [[PTR2:%.*]] = alloca i32, align 128
-; IS__CGSCC____-NEXT:    [[PTR3:%.*]] = alloca i32, align 128
-; IS__CGSCC____-NEXT:    [[PTR4:%.*]] = alloca i32, align 128
 ; IS__CGSCC____-NEXT:    call void @call_via_pointer_with_dead_args(i32* [[A]], i32* noundef nonnull align 128 dereferenceable(4) [[PTR1]], void (i32*, i32*, i32*, i64, i32**)* nocapture nofree noundef nonnull @called_via_pointer)
 ; IS__CGSCC____-NEXT:    call void @call_via_pointer_with_dead_args(i32* [[A]], i32* noundef nonnull align 128 dereferenceable(4) [[PTR2]], void (i32*, i32*, i32*, i64, i32**)* nocapture nofree noundef nonnull @called_via_pointer_internal_1)
-; IS__CGSCC____-NEXT:    call void @call_via_pointer_with_dead_args_internal_a(i32* [[B]], i32* noundef nonnull align 128 dereferenceable(4) [[PTR3]], void (i32*, i32*, i32*, i64, i32**)* nocapture nofree noundef nonnull @called_via_pointer)
-; IS__CGSCC____-NEXT:    call void @call_via_pointer_with_dead_args_internal_b(i32* [[B]], i32* noundef nonnull align 128 dereferenceable(4) [[PTR4]], void (i32*, i32*, i32*, i64, i32**)* nocapture nofree noundef nonnull @called_via_pointer_internal_2)
+; IS__CGSCC____-NEXT:    call void @call_via_pointer_with_dead_args_internal_a(i32* [[B]], i32* noalias nocapture nofree nonnull readnone align 128 dereferenceable(4) undef)
+; IS__CGSCC____-NEXT:    call void @call_via_pointer_with_dead_args_internal_b(i32* [[B]], i32* noalias nocapture nofree nonnull readnone align 128 dereferenceable(4) undef)
 ; IS__CGSCC____-NEXT:    ret void
 ;
   %ptr1 = alloca i32, align 128
@@ -2373,12 +2371,19 @@ entry:
 }
 ; FIXME: Figure out why the MODULE has the unused arguments still
 define internal void @called_via_pointer_internal_2(i32* %a, i32* %b, i32* %c, i64 %d, i32** %e) {
-; CHECK-LABEL: define {{[^@]+}}@called_via_pointer_internal_2
-; CHECK-SAME: (i32* [[A:%.*]], i32* nocapture nofree readnone [[B:%.*]], i32* nocapture nofree readnone [[C:%.*]], i64 [[D:%.*]], i32** nocapture nofree readnone [[E:%.*]]) {
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    tail call void @use_i32p(i32* [[A]])
-; CHECK-NEXT:    tail call void @use_i32p(i32* [[A]])
-; CHECK-NEXT:    ret void
+; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@called_via_pointer_internal_2
+; NOT_CGSCC_NPM-SAME: (i32* [[A:%.*]], i32* nocapture nofree readnone [[B:%.*]], i32* nocapture nofree readnone [[C:%.*]], i64 [[D:%.*]], i32** nocapture nofree readnone [[E:%.*]]) {
+; NOT_CGSCC_NPM-NEXT:  entry:
+; NOT_CGSCC_NPM-NEXT:    tail call void @use_i32p(i32* [[A]])
+; NOT_CGSCC_NPM-NEXT:    tail call void @use_i32p(i32* [[A]])
+; NOT_CGSCC_NPM-NEXT:    ret void
+;
+; IS__CGSCC____-LABEL: define {{[^@]+}}@called_via_pointer_internal_2
+; IS__CGSCC____-SAME: (i32* [[A:%.*]]) {
+; IS__CGSCC____-NEXT:  entry:
+; IS__CGSCC____-NEXT:    tail call void @use_i32p(i32* [[A]])
+; IS__CGSCC____-NEXT:    tail call void @use_i32p(i32* [[A]])
+; IS__CGSCC____-NEXT:    ret void
 ;
 entry:
   tail call void @use_i32p(i32* %a)

diff  --git a/llvm/test/Transforms/Attributor/value-simplify.ll b/llvm/test/Transforms/Attributor/value-simplify.ll
index 69b4b8ba90d33..1315375cad247 100644
--- a/llvm/test/Transforms/Attributor/value-simplify.ll
+++ b/llvm/test/Transforms/Attributor/value-simplify.ll
@@ -903,7 +903,9 @@ define void @test_callee_is_undef(void (i32)* %fn) {
 ;
 ; IS__CGSCC____-LABEL: define {{[^@]+}}@test_callee_is_undef
 ; IS__CGSCC____-SAME: (void (i32)* nocapture nofree [[FN:%.*]]) {
-; IS__CGSCC____-NEXT:    unreachable
+; IS__CGSCC____-NEXT:    call void @callee_is_undef()
+; IS__CGSCC____-NEXT:    call void @unknown_calle_arg_is_undef(void (i32)* nocapture nofree noundef nonnull [[FN]])
+; IS__CGSCC____-NEXT:    ret void
 ;
   call void @callee_is_undef(void ()* undef)
   call void @unknown_calle_arg_is_undef(void (i32)* %fn, i32 undef)
@@ -911,14 +913,9 @@ define void @test_callee_is_undef(void (i32)* %fn) {
 }
 define internal void @callee_is_undef(void ()* %fn) {
 ;
-; IS__TUNIT____-LABEL: define {{[^@]+}}@callee_is_undef() {
-; IS__TUNIT____-NEXT:    call void undef()
-; IS__TUNIT____-NEXT:    ret void
-;
-; IS__CGSCC____-LABEL: define {{[^@]+}}@callee_is_undef
-; IS__CGSCC____-SAME: (void ()* nocapture nofree noundef nonnull align 4294967296 [[FN:%.*]]) {
-; IS__CGSCC____-NEXT:    call void [[FN]]()
-; IS__CGSCC____-NEXT:    ret void
+; CHECK-LABEL: define {{[^@]+}}@callee_is_undef() {
+; CHECK-NEXT:    call void undef()
+; CHECK-NEXT:    ret void
 ;
   call void %fn()
   ret void


        


More information about the llvm-commits mailing list