[llvm] a7ca9e0 - [Attributor] Fix callsite check in AAUndefinedBehavior

Shinji Okumura via llvm-commits llvm-commits at lists.llvm.org
Sat Aug 29 21:21:16 PDT 2020


Author: Shinji Okumura
Date: 2020-08-30T13:17:02+09:00
New Revision: a7ca9e09bd10a989cf920df2fd70f562707c4776

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

LOG: [Attributor] Fix callsite check in AAUndefinedBehavior

This is the next patch of D86842
When we check `noundef` attribute violation at callsites, we do not have to require `nonnull` in the following two cases.
1. An argument is known to be simplified to undef
2. An argument is known to be dead

Reviewed By: jdoerfert

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

Added: 
    

Modified: 
    llvm/lib/Transforms/IPO/AttributorAttributes.cpp
    llvm/test/Transforms/Attributor/undefined_behavior.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
index 83bb8343f0f0..4db44d340b7e 100644
--- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
+++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
@@ -2019,34 +2019,35 @@ struct AAUndefinedBehaviorImpl : public AAUndefinedBehavior {
         if (idx >= Callee->arg_size())
           break;
         Value *ArgVal = CB.getArgOperand(idx);
-        if (!ArgVal || !ArgVal->getType()->isPointerTy())
+        if (!ArgVal)
           continue;
+        // Here, we handle three cases.
+        //   (1) Not having a value means it is dead. (we can replace the value
+        //       with undef)
+        //   (2) Simplified to undef. The argument violate noundef attriubte.
+        //   (3) Simplified to null pointer where known to be nonnull.
+        //       The argument is a poison value and violate noundef attribute.
         IRPosition CalleeArgumentIRP = IRPosition::callsite_argument(CB, idx);
         if (!CalleeArgumentIRP.hasAttr({Attribute::NoUndef}))
           continue;
-        auto &NonNullAA = A.getAAFor<AANonNull>(*this, CalleeArgumentIRP,
-                                                /* TrackDependence */ false);
-        if (!NonNullAA.isKnownNonNull())
-          continue;
-        const auto &ValueSimplifyAA = A.getAAFor<AAValueSimplify>(
+        auto &ValueSimplifyAA = A.getAAFor<AAValueSimplify>(
             *this, IRPosition::value(*ArgVal), /* TrackDependence */ false);
-        Optional<Value *> SimplifiedVal =
-            ValueSimplifyAA.getAssumedSimplifiedValue(A);
-
         if (!ValueSimplifyAA.isKnown())
           continue;
-        // Here, we handle three cases.
-        //   (1) Not having a value means it is dead. (we can replace the value
-        //       with undef)
-        //   (2) Simplified to null pointer. The argument is a poison value and
-        //       violate noundef attribute.
-        //   (3) Simplified to undef. The argument violate noundef attriubte.
+        Optional<Value *> SimplifiedVal =
+            ValueSimplifyAA.getAssumedSimplifiedValue(A);
         if (!SimplifiedVal.hasValue() ||
-            isa<ConstantPointerNull>(*SimplifiedVal.getValue()) ||
             isa<UndefValue>(*SimplifiedVal.getValue())) {
           KnownUBInsts.insert(&I);
-          return true;
+          continue;
         }
+        if (!ArgVal->getType()->isPointerTy() ||
+            !isa<ConstantPointerNull>(*SimplifiedVal.getValue()))
+          continue;
+        auto &NonNullAA = A.getAAFor<AANonNull>(*this, CalleeArgumentIRP,
+                                                /* TrackDependence */ false);
+        if (NonNullAA.isKnownNonNull())
+          KnownUBInsts.insert(&I);
       }
       return true;
     };

diff  --git a/llvm/test/Transforms/Attributor/undefined_behavior.ll b/llvm/test/Transforms/Attributor/undefined_behavior.ll
index 737d4475f96e..50d8f4d2fec4 100644
--- a/llvm/test/Transforms/Attributor/undefined_behavior.ll
+++ b/llvm/test/Transforms/Attributor/undefined_behavior.ll
@@ -1087,3 +1087,61 @@ define void @callsite_noundef_2() {
   call void @callee_ptr_arg(i32* noundef undef)
   ret void
 }
+
+define i32 @argument_noundef1(i32 noundef %c) {
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@argument_noundef1
+; IS__TUNIT____-SAME: (i32 noundef returned [[C:%.*]]) [[ATTR0]] {
+; IS__TUNIT____-NEXT:    ret i32 [[C]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@argument_noundef1
+; IS__CGSCC____-SAME: (i32 noundef returned [[C:%.*]]) [[ATTR0]] {
+; IS__CGSCC____-NEXT:    ret i32 [[C]]
+;
+  ret i32 %c
+}
+
+define i32 @violate_noundef_nonpointer() {
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@violate_noundef_nonpointer
+; IS__TUNIT____-SAME: () [[ATTR0]] {
+; IS__TUNIT____-NEXT:    unreachable
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@violate_noundef_nonpointer
+; IS__CGSCC____-SAME: () [[ATTR0]] {
+; IS__CGSCC____-NEXT:    unreachable
+;
+  %ret = call i32 @argument_noundef1(i32 undef)
+  ret i32 %ret
+}
+
+define i32* @argument_noundef2(i32* noundef %c) {
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@argument_noundef2
+; IS__TUNIT____-SAME: (i32* nofree noundef readnone returned "no-capture-maybe-returned" [[C:%.*]]) [[ATTR0]] {
+; IS__TUNIT____-NEXT:    ret i32* [[C]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@argument_noundef2
+; IS__CGSCC____-SAME: (i32* nofree noundef readnone returned "no-capture-maybe-returned" [[C:%.*]]) [[ATTR0]] {
+; IS__CGSCC____-NEXT:    ret i32* [[C]]
+;
+  ret i32* %c
+}
+
+define i32* @violate_noundef_pointer() {
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@violate_noundef_pointer
+; IS__TUNIT____-SAME: () [[ATTR0]] {
+; IS__TUNIT____-NEXT:    unreachable
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@violate_noundef_pointer
+; IS__CGSCC____-SAME: () [[ATTR0]] {
+; IS__CGSCC____-NEXT:    unreachable
+;
+  %ret = call i32* @argument_noundef2(i32* undef)
+  ret i32* %ret
+}


        


More information about the llvm-commits mailing list