From 1ce06176eccf324ccab0a386b024739e38637a53 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Wed, 18 Jan 2023 13:35:12 -0500 Subject: [PATCH] [InstSimplify] reduce "mul nsw i1" to "false" https://alive2.llvm.org/ce/z/XYGvYg Follow-up for: 68c197f07eeae71 --- llvm/lib/Analysis/InstructionSimplify.cpp | 15 +++++++++++---- llvm/test/Transforms/InstCombine/sub.ll | 5 +---- llvm/test/Transforms/InstSimplify/mul.ll | 5 ++--- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp index 53434c4..20a036c 100644 --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -948,10 +948,17 @@ static Value *simplifyMulInst(Value *Op0, Value *Op1, bool IsNSW, bool IsNUW, match(Op1, m_Exact(m_IDiv(m_Value(X), m_Specific(Op0)))))) // Y * (X / Y) return X; - // i1 mul -> and. - if (MaxRecurse && Op0->getType()->isIntOrIntVectorTy(1)) - if (Value *V = simplifyAndInst(Op0, Op1, Q, MaxRecurse - 1)) - return V; + if (Op0->getType()->isIntOrIntVectorTy(1)) { + // mul i1 nsw is a special-case because -1 * -1 is poison (+1 is not + // representable). All other cases reduce to 0, so just return 0. + if (IsNSW) + return ConstantInt::getNullValue(Op0->getType()); + + // Treat "mul i1" as "and i1". + if (MaxRecurse) + if (Value *V = simplifyAndInst(Op0, Op1, Q, MaxRecurse - 1)) + return V; + } // Try some generic simplifications for associative operations. if (Value *V = diff --git a/llvm/test/Transforms/InstCombine/sub.ll b/llvm/test/Transforms/InstCombine/sub.ll index 96a527e..0bab904 100644 --- a/llvm/test/Transforms/InstCombine/sub.ll +++ b/llvm/test/Transforms/InstCombine/sub.ll @@ -2465,12 +2465,9 @@ define <2 x i5> @diff_of_squares_partial_nsw(<2 x i5> %x, <2 x i5> %y) { ret <2 x i5> %r } -; TODO: This should simplify more. - define i1 @diff_of_squares_nsw_i1(i1 %x, i1 %y) { ; CHECK-LABEL: @diff_of_squares_nsw_i1( -; CHECK-NEXT: [[R:%.*]] = xor i1 [[Y:%.*]], [[X:%.*]] -; CHECK-NEXT: ret i1 [[R]] +; CHECK-NEXT: ret i1 false ; %x2 = mul nsw i1 %x, %x %y2 = mul nsw i1 %y, %y diff --git a/llvm/test/Transforms/InstSimplify/mul.ll b/llvm/test/Transforms/InstSimplify/mul.ll index 443a225..8ae7f1ea 100644 --- a/llvm/test/Transforms/InstSimplify/mul.ll +++ b/llvm/test/Transforms/InstSimplify/mul.ll @@ -61,8 +61,7 @@ define i1 @mul_i1(i1 %x, i1 %y) { define i1 @mul_i1_nsw(i1 %x, i1 %y) { ; CHECK-LABEL: @mul_i1_nsw( -; CHECK-NEXT: [[R:%.*]] = mul nsw i1 [[X:%.*]], [[Y:%.*]] -; CHECK-NEXT: ret i1 [[R]] +; CHECK-NEXT: ret i1 false ; %r = mul nsw i1 %x, %y ret i1 %r @@ -87,7 +86,7 @@ define i1 @square_i1(i1 %x) { define i1 @square_i1_nsw(i1 %x) { ; CHECK-LABEL: @square_i1_nsw( -; CHECK-NEXT: ret i1 [[X:%.*]] +; CHECK-NEXT: ret i1 false ; %r = mul nsw i1 %x, %x ret i1 %r -- 2.7.4