[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