[llvm] e6241cb - [Mem2Reg] Only convert !nonnull to assume if !noundef present

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Fri Jan 20 07:38:34 PST 2023


Author: Nikita Popov
Date: 2023-01-20T16:38:26+01:00
New Revision: e6241cbdcbf3cc9beb49460578466e18936ef220

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

LOG: [Mem2Reg] Only convert !nonnull to assume if !noundef present

After D141386 !nonnull violation returns poison rather than
resulting in immediate undefined behavior. However, converting
it into an assume would result in IUB. As such, we can only
perform this transform if !noundef is also present.

Added: 
    

Modified: 
    llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
    llvm/test/Transforms/ArgumentPromotion/metadata.ll
    llvm/test/Transforms/Mem2Reg/preserve-nonnull-load-metadata.ll
    llvm/test/Transforms/SROA/preserve-metadata.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp b/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
index c71ad2782c050..75ea9dc5dfc0d 100644
--- a/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
+++ b/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
@@ -386,10 +386,12 @@ static void addAssumeNonNull(AssumptionCache *AC, LoadInst *LI) {
 static void convertMetadataToAssumes(LoadInst *LI, Value *Val,
                                      const DataLayout &DL, AssumptionCache *AC,
                                      const DominatorTree *DT) {
-  // If the load was marked as nonnull we don't want to lose
-  // that information when we erase this Load. So we preserve
-  // it with an assume.
+  // If the load was marked as nonnull we don't want to lose that information
+  // when we erase this Load. So we preserve it with an assume. As !nonnull
+  // returns poison while assume violations are immediate undefined behavior,
+  // we can only do this if the value is known non-poison.
   if (AC && LI->getMetadata(LLVMContext::MD_nonnull) &&
+      LI->getMetadata(LLVMContext::MD_noundef) &&
       !isKnownNonZero(Val, DL, 0, AC, LI, DT))
     addAssumeNonNull(AC, LI);
 }

diff  --git a/llvm/test/Transforms/ArgumentPromotion/metadata.ll b/llvm/test/Transforms/ArgumentPromotion/metadata.ll
index 7568f5dd87e82..a25d7a1e8ae31 100644
--- a/llvm/test/Transforms/ArgumentPromotion/metadata.ll
+++ b/llvm/test/Transforms/ArgumentPromotion/metadata.ll
@@ -7,8 +7,8 @@ declare void @use.p32(ptr)
 define internal void @callee(ptr %p1, ptr %p2, ptr %p3, ptr %p4, ptr %p5, ptr %p6, ptr %p7) {
 ; CHECK-LABEL: define {{[^@]+}}@callee
 ; CHECK-SAME: (i32 [[P1_0_VAL:%.*]], ptr [[P2_0_VAL:%.*]], ptr [[P3_0_VAL:%.*]], ptr [[P4_0_VAL:%.*]], ptr [[P5_0_VAL:%.*]], ptr [[P6_0_VAL:%.*]], ptr [[P7_0_VAL:%.*]]) {
-; CHECK-NEXT:    [[IS_NOT_NULL:%.*]] = icmp ne ptr [[P2_0_VAL]], null
-; CHECK-NEXT:    call void @llvm.assume(i1 [[IS_NOT_NULL]])
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne ptr [[P2_0_VAL]], null
+; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP1]])
 ; CHECK-NEXT:    call void @use.i32(i32 [[P1_0_VAL]])
 ; CHECK-NEXT:    call void @use.p32(ptr [[P2_0_VAL]])
 ; CHECK-NEXT:    call void @use.p32(ptr [[P3_0_VAL]])
@@ -19,7 +19,7 @@ define internal void @callee(ptr %p1, ptr %p2, ptr %p3, ptr %p4, ptr %p5, ptr %p
 ; CHECK-NEXT:    ret void
 ;
   %v1 = load i32, ptr %p1, !range !0
-  %v2 = load ptr, ptr %p2, !nonnull !1
+  %v2 = load ptr, ptr %p2, !nonnull !1, !noundef !1
   %v3 = load ptr, ptr %p3, !dereferenceable !2
   %v4 = load ptr, ptr %p4, !dereferenceable_or_null !2
   %v5 = load ptr, ptr %p5, !align !3
@@ -39,7 +39,7 @@ define void @caller(ptr %p1, ptr %p2, ptr %p3, ptr %p4, ptr %p5, ptr %p6, ptr %p
 ; CHECK-LABEL: define {{[^@]+}}@caller
 ; CHECK-SAME: (ptr [[P1:%.*]], ptr [[P2:%.*]], ptr [[P3:%.*]], ptr [[P4:%.*]], ptr [[P5:%.*]], ptr [[P6:%.*]], ptr [[P7:%.*]]) {
 ; CHECK-NEXT:    [[P1_VAL:%.*]] = load i32, ptr [[P1]], align 4, !range [[RNG0:![0-9]+]]
-; CHECK-NEXT:    [[P2_VAL:%.*]] = load ptr, ptr [[P2]], align 8, !nonnull !1
+; CHECK-NEXT:    [[P2_VAL:%.*]] = load ptr, ptr [[P2]], align 8, !nonnull !1, !noundef !1
 ; CHECK-NEXT:    [[P3_VAL:%.*]] = load ptr, ptr [[P3]], align 8, !dereferenceable !2
 ; CHECK-NEXT:    [[P4_VAL:%.*]] = load ptr, ptr [[P4]], align 8, !dereferenceable_or_null !2
 ; CHECK-NEXT:    [[P5_VAL:%.*]] = load ptr, ptr [[P5]], align 8, !align !3
@@ -57,8 +57,8 @@ define internal ptr @callee_conditional(i1 %c, ptr dereferenceable(8) align 8 %p
 ; CHECK-SAME: (i1 [[C:%.*]], ptr [[P_0_VAL:%.*]]) {
 ; CHECK-NEXT:    br i1 [[C]], label [[IF:%.*]], label [[ELSE:%.*]]
 ; CHECK:       if:
-; CHECK-NEXT:    [[IS_NOT_NULL:%.*]] = icmp ne ptr [[P_0_VAL]], null
-; CHECK-NEXT:    call void @llvm.assume(i1 [[IS_NOT_NULL]])
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne ptr [[P_0_VAL]], null
+; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP1]])
 ; CHECK-NEXT:    ret ptr [[P_0_VAL]]
 ; CHECK:       else:
 ; CHECK-NEXT:    ret ptr null
@@ -66,7 +66,7 @@ define internal ptr @callee_conditional(i1 %c, ptr dereferenceable(8) align 8 %p
   br i1 %c, label %if, label %else
 
 if:
-  %v = load ptr, ptr %p, !nonnull !1
+  %v = load ptr, ptr %p, !nonnull !1, !noundef !1
   ret ptr %v
 
 else:

diff  --git a/llvm/test/Transforms/Mem2Reg/preserve-nonnull-load-metadata.ll b/llvm/test/Transforms/Mem2Reg/preserve-nonnull-load-metadata.ll
index f974b9044a5a9..73a68f26f4aed 100644
--- a/llvm/test/Transforms/Mem2Reg/preserve-nonnull-load-metadata.ll
+++ b/llvm/test/Transforms/Mem2Reg/preserve-nonnull-load-metadata.ll
@@ -25,8 +25,6 @@ define ptr @single_store_missing_noundef(ptr %arg) {
 ; CHECK-LABEL: @single_store_missing_noundef(
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    [[ARG_LOAD:%.*]] = load ptr, ptr [[ARG:%.*]], align 8
-; CHECK-NEXT:    [[TMP0:%.*]] = icmp ne ptr [[ARG_LOAD]], null
-; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP0]])
 ; CHECK-NEXT:    ret ptr [[ARG_LOAD]]
 ;
 entry:
@@ -60,8 +58,6 @@ define ptr @single_block_missing_noundef(ptr %arg) {
 ; CHECK-LABEL: @single_block_missing_noundef(
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    [[ARG_LOAD:%.*]] = load ptr, ptr [[ARG:%.*]], align 8
-; CHECK-NEXT:    [[TMP0:%.*]] = icmp ne ptr [[ARG_LOAD]], null
-; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP0]])
 ; CHECK-NEXT:    ret ptr [[ARG_LOAD]]
 ;
 entry:
@@ -102,8 +98,6 @@ define ptr @multi_block_missing_noundef(ptr %arg) {
 ; CHECK-NEXT:    [[ARG_LOAD:%.*]] = load ptr, ptr [[ARG:%.*]], align 8
 ; CHECK-NEXT:    br label [[NEXT:%.*]]
 ; CHECK:       next:
-; CHECK-NEXT:    [[TMP0:%.*]] = icmp ne ptr [[ARG_LOAD]], null
-; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP0]])
 ; CHECK-NEXT:    ret ptr [[ARG_LOAD]]
 ;
 entry:

diff  --git a/llvm/test/Transforms/SROA/preserve-metadata.ll b/llvm/test/Transforms/SROA/preserve-metadata.ll
index 1308c298cd6be..6910a4c0e6ba0 100644
--- a/llvm/test/Transforms/SROA/preserve-metadata.ll
+++ b/llvm/test/Transforms/SROA/preserve-metadata.ll
@@ -74,13 +74,10 @@ entry:
   ret ptr %ret
 }
 
-; FIXME: Should not produce assume.
 define ptr @dont_turn_nonnull_without_noundef_into_assume(ptr %arg) {
 ; CHECK-LABEL: @dont_turn_nonnull_without_noundef_into_assume(
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    [[BUF_0_COPYLOAD:%.*]] = load ptr, ptr [[ARG:%.*]], align 8
-; CHECK-NEXT:    [[TMP0:%.*]] = icmp ne ptr [[BUF_0_COPYLOAD]], null
-; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP0]])
 ; CHECK-NEXT:    ret ptr [[BUF_0_COPYLOAD]]
 ;
 entry:


        


More information about the llvm-commits mailing list