diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -6338,11 +6338,11 @@ } // (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 --- a/llvm/test/Transforms/InstCombine/overflow-mul.ll +++ b/llvm/test/Transforms/InstCombine/overflow-mul.ll @@ -241,3 +241,43 @@ %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) nounwind { +; 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 +} + +; Negative test: mul(zext x, zext y) may overflow. +define i32 @mul_may_overflow_commute(i32 %x, i32 %y) nounwind { +; CHECK-LABEL: @mul_may_overflow_commute( +; 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 uge i34 4294967295, %mul34 + %retval = zext i1 %overflow to i32 + ret i32 %retval +}