[llvm] 232698d - [Local][InstCombine][GVN] Handle !noundef metadata in combineMetadata

via llvm-commits llvm-commits at lists.llvm.org
Wed Feb 1 22:27:17 PST 2023


Author: luxufan
Date: 2023-02-02T14:25:13+08:00
New Revision: 232698dc171ed7e3639db4a18e6d1abfba89f68b

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

LOG: [Local][InstCombine][GVN] Handle !noundef metadata in combineMetadata

Handle !noundef metadata in comhineMetadata. The behavior of violating
!noundef metadata is undefined behavior. So if K dominates J, we can
preserve it uncontionally, otherwise, we preserve it if both K and J
have !noundef metadata been set.

This patch also makes !noundef metadata added in KnownIDs when doing
instruction combine for phi node or global value numbering for loads.

Reviewed By: nikic

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

Added: 
    llvm/test/Transforms/GVN/noundef.ll
    llvm/test/Transforms/InstCombine/phi-load-metadata-4.ll

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp
    llvm/lib/Transforms/Utils/Local.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp b/llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp
index 7f59729f0085e..d5584b77aa826 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp
@@ -745,6 +745,7 @@ Instruction *InstCombinerImpl::foldPHIArgLoadIntoPHI(PHINode &PN) {
     LLVMContext::MD_dereferenceable,
     LLVMContext::MD_dereferenceable_or_null,
     LLVMContext::MD_access_group,
+    LLVMContext::MD_noundef,
   };
 
   for (unsigned ID : KnownIDs)

diff  --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp
index b6c6c5a6b52a3..624907a691de1 100644
--- a/llvm/lib/Transforms/Utils/Local.cpp
+++ b/llvm/lib/Transforms/Utils/Local.cpp
@@ -2713,6 +2713,11 @@ void llvm::combineMetadata(Instruction *K, const Instruction *J,
       case LLVMContext::MD_preserve_access_index:
         // Preserve !preserve.access.index in K.
         break;
+      case LLVMContext::MD_noundef:
+        // If K does move, keep noundef if it is present in both instructions.
+        if (DoesKMove)
+          K->setMetadata(Kind, JMD);
+        break;
     }
   }
   // Set !invariant.group from J if J has it. If both instructions have it
@@ -2819,7 +2824,8 @@ void llvm::patchReplacementInstruction(Instruction *I, Value *Repl) {
       LLVMContext::MD_noalias,         LLVMContext::MD_range,
       LLVMContext::MD_fpmath,          LLVMContext::MD_invariant_load,
       LLVMContext::MD_invariant_group, LLVMContext::MD_nonnull,
-      LLVMContext::MD_access_group,    LLVMContext::MD_preserve_access_index};
+      LLVMContext::MD_access_group,    LLVMContext::MD_preserve_access_index,
+      LLVMContext::MD_noundef};
   combineMetadata(ReplInst, I, KnownIDs, false);
 }
 

diff  --git a/llvm/test/Transforms/GVN/noundef.ll b/llvm/test/Transforms/GVN/noundef.ll
new file mode 100644
index 0000000000000..ea8a54c418065
--- /dev/null
+++ b/llvm/test/Transforms/GVN/noundef.ll
@@ -0,0 +1,28 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -passes=gvn -S %s | FileCheck %s
+;
+;Check that !noundef metadata is combined.
+define i32 @one_noundef(ptr %p) {
+; CHECK-LABEL: @one_noundef(
+; CHECK-NEXT:    [[A:%.*]] = load i32, ptr [[P:%.*]], align 4, !noundef !0
+; CHECK-NEXT:    [[C:%.*]] = add i32 [[A]], [[A]]
+; CHECK-NEXT:    ret i32 [[C]]
+;
+  %a = load i32, ptr %p, !noundef !0
+  %b = load i32, ptr %p
+  %c = add i32 %a, %b
+  ret i32 %c
+}
+
+define i32 @both_noundef(ptr %p) {
+; CHECK-LABEL: @both_noundef(
+; CHECK-NEXT:    [[A:%.*]] = load i32, ptr [[P:%.*]], align 4, !noundef !0
+; CHECK-NEXT:    [[C:%.*]] = add i32 [[A]], [[A]]
+; CHECK-NEXT:    ret i32 [[C]]
+;
+  %a = load i32, ptr %p, !noundef !0
+  %b = load i32, ptr %p, !noundef !0
+  %c = add i32 %a, %b
+  ret i32 %c
+}
+!0 = !{}

diff  --git a/llvm/test/Transforms/InstCombine/phi-load-metadata-4.ll b/llvm/test/Transforms/InstCombine/phi-load-metadata-4.ll
new file mode 100644
index 0000000000000..9d86d189abdca
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/phi-load-metadata-4.ll
@@ -0,0 +1,70 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -passes=instcombine -S < %s | FileCheck %s
+
+declare void @bar()
+declare void @baz()
+
+; Check that !noundef metadata is combined
+define ptr @test_phi_combine_load_metadata(i1 %c, ptr dereferenceable(8) %p1, ptr dereferenceable(8) %p2) {
+; CHECK-LABEL: @test_phi_combine_load_metadata(
+; CHECK-NEXT:    br i1 [[C:%.*]], label [[T:%.*]], label [[F:%.*]]
+; CHECK:       t:
+; CHECK-NEXT:    call void @bar()
+; CHECK-NEXT:    br label [[CONT:%.*]]
+; CHECK:       f:
+; CHECK-NEXT:    call void @baz()
+; CHECK-NEXT:    br label [[CONT]]
+; CHECK:       cont:
+; CHECK-NEXT:    [[RES_IN:%.*]] = phi ptr [ [[P1:%.*]], [[T]] ], [ [[P2:%.*]], [[F]] ]
+; CHECK-NEXT:    [[RES:%.*]] = load ptr, ptr [[RES_IN]], align 8, !noundef !0
+; CHECK-NEXT:    ret ptr [[RES]]
+;
+  br i1 %c, label %t, label %f
+t:
+  call void @bar()
+  %v1 = load ptr, ptr %p1, align 8, !noundef !0
+  br label %cont
+
+f:
+  call void @baz()
+  %v2 = load ptr, ptr %p2, align 8, !noundef !0
+  br label %cont
+
+cont:
+  %res = phi ptr [ %v1, %t ], [ %v2, %f ]
+  ret ptr %res
+}
+
+; Check that !noundef metadata is not combined as a result of
+; there is a load don't have a noundef metadata.
+define ptr @test_phi_combine_load_metadata_negative(i1 %c, ptr dereferenceable(8) %p1, ptr dereferenceable(8) %p2) {
+; CHECK-LABEL: @test_phi_combine_load_metadata_negative(
+; CHECK-NEXT:    br i1 [[C:%.*]], label [[T:%.*]], label [[F:%.*]]
+; CHECK:       t:
+; CHECK-NEXT:    call void @bar()
+; CHECK-NEXT:    br label [[CONT:%.*]]
+; CHECK:       f:
+; CHECK-NEXT:    call void @baz()
+; CHECK-NEXT:    br label [[CONT]]
+; CHECK:       cont:
+; CHECK-NEXT:    [[RES_IN:%.*]] = phi ptr [ [[P1:%.*]], [[T]] ], [ [[P2:%.*]], [[F]] ]
+; CHECK-NEXT:    [[RES:%.*]] = load ptr, ptr [[RES_IN]], align 8
+; CHECK-NEXT:    ret ptr [[RES]]
+;
+  br i1 %c, label %t, label %f
+t:
+  call void @bar()
+  %v1 = load ptr, ptr %p1, align 8, !noundef !0
+  br label %cont
+
+f:
+  call void @baz()
+  %v2 = load ptr, ptr %p2, align 8
+  br label %cont
+
+cont:
+  %res = phi ptr [ %v1, %t ], [ %v2, %f ]
+  ret ptr %res
+}
+
+!0 = !{}


        


More information about the llvm-commits mailing list