[llvm] 076581f - [ValueTracking] Implement sdiv/udiv support for isKnownNonNullFromDominatingCondition (#67282)

via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 19 20:54:37 PDT 2023


Author: Dhruv Chawla
Date: 2023-10-20T09:24:33+05:30
New Revision: 076581fd95af72c8e6d2ab900b6d1798e2efaf8f

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

LOG: [ValueTracking] Implement sdiv/udiv support for isKnownNonNullFromDominatingCondition (#67282)

The second operand of a sdiv/udiv has to be non-null, as division by
zero is UB.

Proofs: https://alive2.llvm.org/ce/z/WttZbb

Fixes https://github.com/llvm/llvm-project/issues/64240.

Added: 
    

Modified: 
    llvm/lib/Analysis/ValueTracking.cpp
    llvm/test/Analysis/ValueTracking/select-known-non-zero.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 1e0281b3f1bd79e..8824a05e3aa6ccd 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -2264,6 +2264,10 @@ static bool isKnownNonNullFromDominatingCondition(const Value *V,
         return true;
     }
 
+    if (match(U, m_IDiv(m_Value(), m_Specific(V))) &&
+        isValidAssumeForContext(cast<Instruction>(U), CtxI, DT))
+      return true;
+
     // Consider only compare instructions uniquely controlling a branch
     Value *RHS;
     CmpInst::Predicate Pred;

diff  --git a/llvm/test/Analysis/ValueTracking/select-known-non-zero.ll b/llvm/test/Analysis/ValueTracking/select-known-non-zero.ll
index 8b1d2fd0181d66c..1dc88412041d34f 100644
--- a/llvm/test/Analysis/ValueTracking/select-known-non-zero.ll
+++ b/llvm/test/Analysis/ValueTracking/select-known-non-zero.ll
@@ -393,3 +393,57 @@ define i1 @inv_select_v_sle_nonneg(i8 %v, i8 %C, i8 %y) {
   %r = icmp eq i8 %s, 0
   ret i1 %r
 }
+
+; Check udiv/sdiv occuring before icmp.
+define i64 @incorrect_safe_div_1(i64 %n, i64 %d) {
+; CHECK-LABEL: @incorrect_safe_div_1(
+; CHECK-NEXT:    [[TMP1:%.*]] = udiv i64 [[N:%.*]], [[D:%.*]]
+; CHECK-NEXT:    ret i64 [[TMP1]]
+;
+  %1 = udiv i64 %n, %d
+  %2 = icmp eq i64 %d, 0
+  %3 = select i1 %2, i64 -1, i64 %1
+  ret i64 %3
+}
+
+; Check icmp occuring before udiv/sdiv.
+define i64 @incorrect_safe_div_2(i64 %n, i64 %d) {
+; CHECK-LABEL: @incorrect_safe_div_2(
+; CHECK-NEXT:    [[TMP1:%.*]] = sdiv i64 [[N:%.*]], [[D:%.*]]
+; CHECK-NEXT:    ret i64 [[TMP1]]
+;
+  %1 = icmp eq i64 %d, 0
+  %2 = sdiv i64 %n, %d
+  %3 = select i1 %1, i64 -1, i64 %2
+  ret i64 %3
+}
+
+define i64 @incorrect_safe_div_call_1(i64 %n, i64 %d) {
+; CHECK-LABEL: @incorrect_safe_div_call_1(
+; CHECK-NEXT:    [[TMP1:%.*]] = sdiv i64 [[N:%.*]], [[D:%.*]]
+; CHECK-NEXT:    tail call void @use(i64 [[D]])
+; CHECK-NEXT:    ret i64 [[TMP1]]
+;
+  %1 = sdiv i64 %n, %d
+  tail call void @use(i64 %d)
+  %2 = icmp eq i64 %d, 0
+  %3 = select i1 %2, i64 -1, i64 %1
+  ret i64 %3
+}
+
+define i64 @incorrect_safe_div_call_2(i64 %n, i64 %d) {
+; CHECK-LABEL: @incorrect_safe_div_call_2(
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i64 [[D:%.*]], 0
+; CHECK-NEXT:    tail call void @use(i64 [[D]])
+; CHECK-NEXT:    [[TMP2:%.*]] = udiv i64 [[N:%.*]], [[D]]
+; CHECK-NEXT:    [[TMP3:%.*]] = select i1 [[TMP1]], i64 -1, i64 [[TMP2]]
+; CHECK-NEXT:    ret i64 [[TMP3]]
+;
+  %1 = icmp eq i64 %d, 0
+  tail call void @use(i64 %d)
+  %2 = udiv i64 %n, %d
+  %3 = select i1 %1, i64 -1, i64 %2
+  ret i64 %3
+}
+
+declare void @use(i64)


        


More information about the llvm-commits mailing list