[PATCH] D127754: [ValueTracking] recognize sub X, (X -nsw Y) as not overflowing

Sanjay Patel via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 14 11:53:40 PDT 2022


This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG8605b4d8c5cc: [ValueTracking] recognize sub X, (X -nsw Y) as not overflowing (authored by spatel).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D127754/new/

https://reviews.llvm.org/D127754

Files:
  llvm/lib/Analysis/ValueTracking.cpp
  llvm/test/Transforms/InstCombine/sub.ll


Index: llvm/test/Transforms/InstCombine/sub.ll
===================================================================
--- llvm/test/Transforms/InstCombine/sub.ll
+++ llvm/test/Transforms/InstCombine/sub.ll
@@ -1847,10 +1847,7 @@
 
 define i16 @sext_nsw_noundef(i8 noundef %x, i8 %y) {
 ; CHECK-LABEL: @sext_nsw_noundef(
-; CHECK-NEXT:    [[D:%.*]] = sub nsw i8 [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[EX:%.*]] = sext i8 [[X]] to i16
-; CHECK-NEXT:    [[ED:%.*]] = sext i8 [[D]] to i16
-; CHECK-NEXT:    [[Z:%.*]] = sub nsw i16 [[EX]], [[ED]]
+; CHECK-NEXT:    [[Z:%.*]] = sext i8 [[Y:%.*]] to i16
 ; CHECK-NEXT:    ret i16 [[Z]]
 ;
   %d = sub nsw i8 %x, %y
@@ -1860,6 +1857,8 @@
   ret i16 %z
 }
 
+; negative test - requires noundef
+
 define i16 @sext_nsw(i8 %x, i8 %y) {
 ; CHECK-LABEL: @sext_nsw(
 ; CHECK-NEXT:    [[D:%.*]] = sub nsw i8 [[X:%.*]], [[Y:%.*]]
@@ -1875,6 +1874,8 @@
   ret i16 %z
 }
 
+; negative test - requires nsw
+
 define i16 @sext_noundef(i8 noundef %x, i8 %y) {
 ; CHECK-LABEL: @sext_noundef(
 ; CHECK-NEXT:    [[D:%.*]] = sub i8 [[X:%.*]], [[Y:%.*]]
@@ -1890,6 +1891,8 @@
   ret i16 %z
 }
 
+; negative test - must have common operand
+
 define i16 @sext_nsw_noundef_wrong_val(i8 noundef %x, i8 noundef %y, i8 noundef %q) {
 ; CHECK-LABEL: @sext_nsw_noundef_wrong_val(
 ; CHECK-NEXT:    [[D:%.*]] = sub nsw i8 [[X:%.*]], [[Y:%.*]]
@@ -1905,13 +1908,12 @@
   ret i16 %z
 }
 
+; two no-wrap analyses combine to allow reduction
+
 define i16 @srem_sext_noundef(i8 noundef %x, i8 %y) {
 ; CHECK-LABEL: @srem_sext_noundef(
 ; CHECK-NEXT:    [[R:%.*]] = srem i8 [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[D:%.*]] = sub nsw i8 [[X]], [[R]]
-; CHECK-NEXT:    [[SD:%.*]] = sext i8 [[D]] to i16
-; CHECK-NEXT:    [[SX:%.*]] = sext i8 [[X]] to i16
-; CHECK-NEXT:    [[Z:%.*]] = sub nsw i16 [[SX]], [[SD]]
+; CHECK-NEXT:    [[Z:%.*]] = sext i8 [[R]] to i16
 ; CHECK-NEXT:    ret i16 [[Z]]
 ;
   %r = srem i8 %x, %y
Index: llvm/lib/Analysis/ValueTracking.cpp
===================================================================
--- llvm/lib/Analysis/ValueTracking.cpp
+++ llvm/lib/Analysis/ValueTracking.cpp
@@ -4987,9 +4987,15 @@
   // X - (X % ?)
   // The remainder of a value can't have greater magnitude than itself,
   // so the subtraction can't overflow.
-  if (match(RHS, m_SRem(m_Specific(LHS), m_Value())) &&
-      isGuaranteedNotToBeUndefOrPoison(LHS, AC, CxtI, DT))
-    return OverflowResult::NeverOverflows;
+
+  // X - (X -nsw ?)
+  // In the minimal case, this would simplify to "?", so there's no subtract
+  // at all. But if this analysis is used to peek through casts, for example,
+  // then determining no-overflow may allow other transforms.
+  if (match(RHS, m_SRem(m_Specific(LHS), m_Value())) ||
+      match(RHS, m_NSWSub(m_Specific(LHS), m_Value())))
+    if (isGuaranteedNotToBeUndefOrPoison(LHS, AC, CxtI, DT))
+      return OverflowResult::NeverOverflows;
 
   // If LHS and RHS each have at least two sign bits, the subtraction
   // cannot overflow.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D127754.436873.patch
Type: text/x-patch
Size: 2995 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220614/ef7929a6/attachment.bin>


More information about the llvm-commits mailing list