[llvm] fa496ce - [Intrinsic] Give "is.constant" the "convergent" attribute

Bill Wendling via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 30 11:47:29 PDT 2020


Author: Bill Wendling
Date: 2020-03-30T11:47:12-07:00
New Revision: fa496ce3c6774097080c8a9cb808da56f383b938

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

LOG: [Intrinsic] Give "is.constant" the "convergent" attribute

Summary:
Code frequently relies upon the results of "is.constant" intrinsics to
DCE invalid code paths. We don't want the intrinsic to be made control-
dependent on any additional values. For instance, we can't split a PHI
into a "constant" and "non-constant" part via jump threading in order
to "optimize" the constant part, because the "is.constant" intrinsic is
meant to return "false".

Reviewers: wmi, kazu, MaskRay

Reviewed By: kazu

Subscribers: jdoerfert, efriedma, joerg, lebedev.ri, nikic, xbolva00, hiraditya, llvm-commits

Tags: #llvm

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

Added: 
    llvm/test/Transforms/JumpThreading/is_constant.ll

Modified: 
    llvm/include/llvm/IR/Intrinsics.td

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td
index 0812d707e4fe..eda69b31fdb2 100644
--- a/llvm/include/llvm/IR/Intrinsics.td
+++ b/llvm/include/llvm/IR/Intrinsics.td
@@ -1151,7 +1151,9 @@ def int_clear_cache : Intrinsic<[], [llvm_ptr_ty, llvm_ptr_ty],
                                 [], "llvm.clear_cache">;
 
 // Intrinsic to detect whether its argument is a constant.
-def int_is_constant : Intrinsic<[llvm_i1_ty], [llvm_any_ty], [IntrNoMem, IntrWillReturn], "llvm.is.constant">;
+def int_is_constant : Intrinsic<[llvm_i1_ty], [llvm_any_ty],
+                                [IntrNoMem, IntrWillReturn, IntrConvergent],
+                                "llvm.is.constant">;
 
 // Intrinsic to mask out bits of a pointer.
 def int_ptrmask: Intrinsic<[llvm_anyptr_ty], [llvm_anyptr_ty, llvm_anyint_ty],

diff  --git a/llvm/test/Transforms/JumpThreading/is_constant.ll b/llvm/test/Transforms/JumpThreading/is_constant.ll
new file mode 100644
index 000000000000..12d0451ef095
--- /dev/null
+++ b/llvm/test/Transforms/JumpThreading/is_constant.ll
@@ -0,0 +1,40 @@
+; RUN: opt -jump-threading -S -verify < %s | FileCheck %s
+
+; This is reduced from the Linux net/ipv4/tcp.c file built with ASAN. We
+; don't want jump threading to split up a basic block which has a PHI node with
+; at least one constant incoming value, whose value is used by an is.constant
+; intrinsic with non-local uses. It could lead to later passes no DCE'ing
+; invalid paths.
+
+; CHECK-LABEL:    define void @test1(
+; CHECK-LABEL:    bb_cond:
+; CHECK-NOT:        %sext = phi i64 [ %var, %entry ]
+; CHECK-NEXT:       %sext = phi i64 [ 24, %bb_constant ], [ %var, %entry ]
+; CHECK-NEXT:       %cond2 = icmp
+; CHECK-NEXT:       call i1 @llvm.is.constant.i64(
+
+define void @test1(i32 %a, i64 %var) {
+entry:
+  %cond1 = icmp ugt i32 %a, 24
+  br i1 %cond1, label %bb_constant, label %bb_cond
+
+bb_constant:
+  br label %bb_cond
+
+bb_cond:
+  %sext = phi i64 [ 24, %bb_constant ], [ %var, %entry ]
+  %cond2 = icmp ugt i64 %sext, 24
+  %is_constant = call i1 @llvm.is.constant.i64(i64 %sext)
+  br i1 %cond2, label %bb_then, label %bb_else
+
+bb_then:
+  unreachable
+
+bb_else:
+  unreachable
+}
+
+; Function Attrs: nounwind readnone willreturn
+declare i1 @llvm.is.constant.i64(i64) #0
+
+attributes #0 = { convergent nounwind readnone willreturn }


        


More information about the llvm-commits mailing list