[llvm] eda8e99 - [InstCombine] Combine (zext a) mul (zext b) to llvm.umul.with.overflow only if mul has NUW flag

via llvm-commits llvm-commits at lists.llvm.org
Sat Jan 7 22:42:20 PST 2023


Author: luxufan
Date: 2023-01-08T14:41:59+08:00
New Revision: eda8e999dd01e9a741a43330b693cff94d4cb955

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

LOG: [InstCombine] Combine (zext a) mul (zext b) to llvm.umul.with.overflow only if mul has NUW flag

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

Reviewed By: nikic

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

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
    llvm/test/Transforms/InstCombine/overflow-mul.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 2d9a27a5eacfa..b0ebfcf919668 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -6338,11 +6338,11 @@ Instruction *InstCombinerImpl::visitICmpInst(ICmpInst &I) {
     }
 
     // (zext a) * (zext b)  --> llvm.umul.with.overflow.
-    if (match(Op0, m_Mul(m_ZExt(m_Value(A)), m_ZExt(m_Value(B))))) {
+    if (match(Op0, m_NUWMul(m_ZExt(m_Value(A)), m_ZExt(m_Value(B))))) {
       if (Instruction *R = processUMulZExtIdiom(I, Op0, Op1, *this))
         return R;
     }
-    if (match(Op1, m_Mul(m_ZExt(m_Value(A)), m_ZExt(m_Value(B))))) {
+    if (match(Op1, m_NUWMul(m_ZExt(m_Value(A)), m_ZExt(m_Value(B))))) {
       if (Instruction *R = processUMulZExtIdiom(I, Op1, Op0, *this))
         return R;
     }

diff  --git a/llvm/test/Transforms/InstCombine/overflow-mul.ll b/llvm/test/Transforms/InstCombine/overflow-mul.ll
index f80431c871475..96d754f27d34a 100644
--- a/llvm/test/Transforms/InstCombine/overflow-mul.ll
+++ b/llvm/test/Transforms/InstCombine/overflow-mul.ll
@@ -241,3 +241,41 @@ define i1 @pr21445(i8 %a) {
   %cmp = icmp ne i32 %mul, %and
   ret i1 %cmp
 }
+
+; Negative test: mul(zext x, zext y) may overflow.
+define i32 @mul_may_overflow(i32 %x, i32 %y) {
+; CHECK-LABEL: @mul_may_overflow(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[L:%.*]] = zext i32 [[X:%.*]] to i34
+; CHECK-NEXT:    [[R:%.*]] = zext i32 [[Y:%.*]] to i34
+; CHECK-NEXT:    [[MUL34:%.*]] = mul i34 [[L]], [[R]]
+; CHECK-NEXT:    [[OVERFLOW:%.*]] = icmp ult i34 [[MUL34]], 4294967296
+; CHECK-NEXT:    [[RETVAL:%.*]] = zext i1 [[OVERFLOW]] to i32
+; CHECK-NEXT:    ret i32 [[RETVAL]]
+;
+entry:
+  %l = zext i32 %x to i34
+  %r = zext i32 %y to i34
+  %mul34 = mul i34 %l, %r
+  %overflow = icmp ule i34 %mul34, 4294967295
+  %retval = zext i1 %overflow to i32
+  ret i32 %retval
+}
+
+define i32 @mul_known_nuw(i32 %x, i32 %y) {
+; CHECK-LABEL: @mul_known_nuw(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[UMUL:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[X:%.*]], i32 [[Y:%.*]])
+; CHECK-NEXT:    [[TMP0:%.*]] = extractvalue { i32, i1 } [[UMUL]], 1
+; CHECK-NEXT:    [[OVERFLOW:%.*]] = xor i1 [[TMP0]], true
+; CHECK-NEXT:    [[RETVAL:%.*]] = zext i1 [[OVERFLOW]] to i32
+; CHECK-NEXT:    ret i32 [[RETVAL]]
+;
+entry:
+  %l = zext i32 %x to i34
+  %r = zext i32 %y to i34
+  %mul34 = mul nuw i34 %l, %r
+  %overflow = icmp ule i34 %mul34, 4294967295
+  %retval = zext i1 %overflow to i32
+  ret i32 %retval
+}


        


More information about the llvm-commits mailing list