Index: llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp =================================================================== --- llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp +++ llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp @@ -1267,6 +1267,47 @@ return NewShl; } +/// Reduce a sequence of masked half-width multiplies to a single multiply. +/// ((XLow * YHigh) + (YLow * XHigh)) << HalfBits) + (XLow * YLow) --> X * Y +static Instruction *foldBoxMultiply(BinaryOperator &I) { + if (!I.getType()->isIntegerTy()) + return nullptr; + + unsigned BitWidth = I.getType()->getScalarSizeInBits(); + // Skip the odd bitwidth types and large bitwidth types + if ((BitWidth & 0x1) || (BitWidth > 128)) + return nullptr; + + unsigned HalfBits = BitWidth >> 1; + APInt HalfMask = APInt::getMaxValue(HalfBits); + + // ResLo = (CrossSum << HalfBits) + (YLo * XLo) + Value *XLo, *YLo; + Value *CrossSum; + if (!match(&I, m_c_Add(m_Shl(m_Value(CrossSum), m_SpecificInt(HalfBits)), + m_Mul(m_Value(YLo), m_Value(XLo))))) + return nullptr; + + // XLo = X & HalfMask + // YLo = Y & HalfMask + Value *X, *Y; + if (!match(XLo, m_And(m_Value(X), m_SpecificInt(HalfMask))) || + !match(YLo, m_And(m_Value(Y), m_SpecificInt(HalfMask)))) + return nullptr; + + // CrossSum = (X' * (Y >> Halfbits)) + (Y' * (X >> HalfBits)) + // X' can be either X or XLo in the pattern (and the same for Y') + if (match(CrossSum, + m_c_Add(m_c_Mul(m_LShr(m_Specific(Y), m_SpecificInt(HalfBits)), + m_CombineOr(m_Specific(X), m_Specific(XLo))), + + m_c_Mul(m_LShr(m_Specific(X), m_SpecificInt(HalfBits)), + m_CombineOr(m_Specific(Y), m_Specific(YLo)))))) + return BinaryOperator::CreateMul(X, Y); + + return nullptr; +} + Instruction *InstCombinerImpl::visitAdd(BinaryOperator &I) { if (Value *V = simplifyAddInst(I.getOperand(0), I.getOperand(1), I.hasNoSignedWrap(), I.hasNoUnsignedWrap(), @@ -1286,6 +1327,9 @@ if (Value *V = SimplifyUsingDistributiveLaws(I)) return replaceInstUsesWith(I, V); + if (Instruction *R = foldBoxMultiply(I)) + return R; + if (Instruction *R = factorizeMathWithShlOps(I, Builder)) return R; Index: llvm/test/Transforms/InstCombine/mul.ll =================================================================== --- llvm/test/Transforms/InstCombine/mul.ll +++ llvm/test/Transforms/InstCombine/mul.ll @@ -1580,16 +1580,7 @@ ; The different _Bx suffix hints the variety of combinations ADD define i64 @mul64_low_A0_B0(i64 noundef %in0, i64 noundef %in1) { ; CHECK-LABEL: @mul64_low_A0_B0( -; CHECK-NEXT: [[IN0LO:%.*]] = and i64 [[IN0:%.*]], 4294967295 -; CHECK-NEXT: [[IN0HI:%.*]] = lshr i64 [[IN0]], 32 -; CHECK-NEXT: [[IN1LO:%.*]] = and i64 [[IN1:%.*]], 4294967295 -; CHECK-NEXT: [[IN1HI:%.*]] = lshr i64 [[IN1]], 32 -; CHECK-NEXT: [[M10:%.*]] = mul i64 [[IN1HI]], [[IN0]] -; CHECK-NEXT: [[M01:%.*]] = mul i64 [[IN0HI]], [[IN1]] -; CHECK-NEXT: [[M00:%.*]] = mul nuw i64 [[IN1LO]], [[IN0LO]] -; CHECK-NEXT: [[ADDC:%.*]] = add i64 [[M10]], [[M01]] -; CHECK-NEXT: [[SHL:%.*]] = shl i64 [[ADDC]], 32 -; CHECK-NEXT: [[ADDC9:%.*]] = add i64 [[SHL]], [[M00]] +; CHECK-NEXT: [[ADDC9:%.*]] = mul i64 [[IN0:%.*]], [[IN1:%.*]] ; CHECK-NEXT: ret i64 [[ADDC9]] ; %In0Lo = and i64 %in0, 4294967295 @@ -1607,16 +1598,7 @@ define i64 @mul64_low_A0_B1(i64 noundef %in0, i64 noundef %in1) { ; CHECK-LABEL: @mul64_low_A0_B1( -; CHECK-NEXT: [[IN0LO:%.*]] = and i64 [[IN0:%.*]], 4294967295 -; CHECK-NEXT: [[IN0HI:%.*]] = lshr i64 [[IN0]], 32 -; CHECK-NEXT: [[IN1LO:%.*]] = and i64 [[IN1:%.*]], 4294967295 -; CHECK-NEXT: [[IN1HI:%.*]] = lshr i64 [[IN1]], 32 -; CHECK-NEXT: [[M10:%.*]] = mul i64 [[IN1HI]], [[IN0]] -; CHECK-NEXT: [[M01:%.*]] = mul i64 [[IN0HI]], [[IN1]] -; CHECK-NEXT: [[M00:%.*]] = mul nuw i64 [[IN1LO]], [[IN0LO]] -; CHECK-NEXT: [[ADDC:%.*]] = add i64 [[M10]], [[M01]] -; CHECK-NEXT: [[SHL:%.*]] = shl i64 [[ADDC]], 32 -; CHECK-NEXT: [[ADDC9:%.*]] = add i64 [[M00]], [[SHL]] +; CHECK-NEXT: [[ADDC9:%.*]] = mul i64 [[IN0:%.*]], [[IN1:%.*]] ; CHECK-NEXT: ret i64 [[ADDC9]] ; %In0Lo = and i64 %in0, 4294967295 @@ -1634,16 +1616,7 @@ define i64 @mul64_low_A0_B2(i64 noundef %in0, i64 noundef %in1) { ; CHECK-LABEL: @mul64_low_A0_B2( -; CHECK-NEXT: [[IN0LO:%.*]] = and i64 [[IN0:%.*]], 4294967295 -; CHECK-NEXT: [[IN0HI:%.*]] = lshr i64 [[IN0]], 32 -; CHECK-NEXT: [[IN1LO:%.*]] = and i64 [[IN1:%.*]], 4294967295 -; CHECK-NEXT: [[IN1HI:%.*]] = lshr i64 [[IN1]], 32 -; CHECK-NEXT: [[M10:%.*]] = mul i64 [[IN1HI]], [[IN0]] -; CHECK-NEXT: [[M01:%.*]] = mul i64 [[IN0HI]], [[IN1]] -; CHECK-NEXT: [[M00:%.*]] = mul nuw i64 [[IN1LO]], [[IN0LO]] -; CHECK-NEXT: [[ADDC:%.*]] = add i64 [[M01]], [[M10]] -; CHECK-NEXT: [[SHL:%.*]] = shl i64 [[ADDC]], 32 -; CHECK-NEXT: [[ADDC9:%.*]] = add i64 [[SHL]], [[M00]] +; CHECK-NEXT: [[ADDC9:%.*]] = mul i64 [[IN0:%.*]], [[IN1:%.*]] ; CHECK-NEXT: ret i64 [[ADDC9]] ; %In0Lo = and i64 %in0, 4294967295 @@ -1661,16 +1634,7 @@ define i64 @mul64_low_A0_B3(i64 noundef %in0, i64 noundef %in1) { ; CHECK-LABEL: @mul64_low_A0_B3( -; CHECK-NEXT: [[IN0LO:%.*]] = and i64 [[IN0:%.*]], 4294967295 -; CHECK-NEXT: [[IN0HI:%.*]] = lshr i64 [[IN0]], 32 -; CHECK-NEXT: [[IN1LO:%.*]] = and i64 [[IN1:%.*]], 4294967295 -; CHECK-NEXT: [[IN1HI:%.*]] = lshr i64 [[IN1]], 32 -; CHECK-NEXT: [[M10:%.*]] = mul i64 [[IN1HI]], [[IN0]] -; CHECK-NEXT: [[M01:%.*]] = mul i64 [[IN0HI]], [[IN1]] -; CHECK-NEXT: [[M00:%.*]] = mul nuw i64 [[IN1LO]], [[IN0LO]] -; CHECK-NEXT: [[ADDC:%.*]] = add i64 [[M01]], [[M10]] -; CHECK-NEXT: [[SHL:%.*]] = shl i64 [[ADDC]], 32 -; CHECK-NEXT: [[ADDC9:%.*]] = add i64 [[M00]], [[SHL]] +; CHECK-NEXT: [[ADDC9:%.*]] = mul i64 [[IN0:%.*]], [[IN1:%.*]] ; CHECK-NEXT: ret i64 [[ADDC9]] ; %In0Lo = and i64 %in0, 4294967295 @@ -1688,16 +1652,7 @@ define i64 @mul64_low_A1_B0(i64 noundef %in0, i64 noundef %in1) { ; CHECK-LABEL: @mul64_low_A1_B0( -; CHECK-NEXT: [[IN0LO:%.*]] = and i64 [[IN0:%.*]], 4294967295 -; CHECK-NEXT: [[IN0HI:%.*]] = lshr i64 [[IN0]], 32 -; CHECK-NEXT: [[IN1LO:%.*]] = and i64 [[IN1:%.*]], 4294967295 -; CHECK-NEXT: [[IN1HI:%.*]] = lshr i64 [[IN1]], 32 -; CHECK-NEXT: [[M10:%.*]] = mul i64 [[IN1HI]], [[IN0]] -; CHECK-NEXT: [[M01:%.*]] = mul i64 [[IN0HI]], [[IN1]] -; CHECK-NEXT: [[M00:%.*]] = mul nuw i64 [[IN1LO]], [[IN0LO]] -; CHECK-NEXT: [[ADDC:%.*]] = add i64 [[M10]], [[M01]] -; CHECK-NEXT: [[SHL:%.*]] = shl i64 [[ADDC]], 32 -; CHECK-NEXT: [[ADDC9:%.*]] = add i64 [[SHL]], [[M00]] +; CHECK-NEXT: [[ADDC9:%.*]] = mul i64 [[IN0:%.*]], [[IN1:%.*]] ; CHECK-NEXT: ret i64 [[ADDC9]] ; %In0Lo = and i64 %in0, 4294967295 @@ -1715,16 +1670,7 @@ define i64 @mul64_low_A1_B1(i64 noundef %in0, i64 noundef %in1) { ; CHECK-LABEL: @mul64_low_A1_B1( -; CHECK-NEXT: [[IN0LO:%.*]] = and i64 [[IN0:%.*]], 4294967295 -; CHECK-NEXT: [[IN0HI:%.*]] = lshr i64 [[IN0]], 32 -; CHECK-NEXT: [[IN1LO:%.*]] = and i64 [[IN1:%.*]], 4294967295 -; CHECK-NEXT: [[IN1HI:%.*]] = lshr i64 [[IN1]], 32 -; CHECK-NEXT: [[M10:%.*]] = mul i64 [[IN1HI]], [[IN0]] -; CHECK-NEXT: [[M01:%.*]] = mul i64 [[IN0HI]], [[IN1]] -; CHECK-NEXT: [[M00:%.*]] = mul nuw i64 [[IN1LO]], [[IN0LO]] -; CHECK-NEXT: [[ADDC:%.*]] = add i64 [[M10]], [[M01]] -; CHECK-NEXT: [[SHL:%.*]] = shl i64 [[ADDC]], 32 -; CHECK-NEXT: [[ADDC9:%.*]] = add i64 [[M00]], [[SHL]] +; CHECK-NEXT: [[ADDC9:%.*]] = mul i64 [[IN0:%.*]], [[IN1:%.*]] ; CHECK-NEXT: ret i64 [[ADDC9]] ; %In0Lo = and i64 %in0, 4294967295 @@ -1742,16 +1688,7 @@ define i64 @mul64_low_A1_B2(i64 noundef %in0, i64 noundef %in1) { ; CHECK-LABEL: @mul64_low_A1_B2( -; CHECK-NEXT: [[IN0LO:%.*]] = and i64 [[IN0:%.*]], 4294967295 -; CHECK-NEXT: [[IN0HI:%.*]] = lshr i64 [[IN0]], 32 -; CHECK-NEXT: [[IN1LO:%.*]] = and i64 [[IN1:%.*]], 4294967295 -; CHECK-NEXT: [[IN1HI:%.*]] = lshr i64 [[IN1]], 32 -; CHECK-NEXT: [[M10:%.*]] = mul i64 [[IN1HI]], [[IN0]] -; CHECK-NEXT: [[M01:%.*]] = mul i64 [[IN0HI]], [[IN1]] -; CHECK-NEXT: [[M00:%.*]] = mul nuw i64 [[IN1LO]], [[IN0LO]] -; CHECK-NEXT: [[ADDC:%.*]] = add i64 [[M01]], [[M10]] -; CHECK-NEXT: [[SHL:%.*]] = shl i64 [[ADDC]], 32 -; CHECK-NEXT: [[ADDC9:%.*]] = add i64 [[SHL]], [[M00]] +; CHECK-NEXT: [[ADDC9:%.*]] = mul i64 [[IN0:%.*]], [[IN1:%.*]] ; CHECK-NEXT: ret i64 [[ADDC9]] ; %In0Lo = and i64 %in0, 4294967295 @@ -1769,16 +1706,7 @@ define i64 @mul64_low_A1_B3(i64 noundef %in0, i64 noundef %in1) { ; CHECK-LABEL: @mul64_low_A1_B3( -; CHECK-NEXT: [[IN0LO:%.*]] = and i64 [[IN0:%.*]], 4294967295 -; CHECK-NEXT: [[IN0HI:%.*]] = lshr i64 [[IN0]], 32 -; CHECK-NEXT: [[IN1LO:%.*]] = and i64 [[IN1:%.*]], 4294967295 -; CHECK-NEXT: [[IN1HI:%.*]] = lshr i64 [[IN1]], 32 -; CHECK-NEXT: [[M10:%.*]] = mul i64 [[IN1HI]], [[IN0]] -; CHECK-NEXT: [[M01:%.*]] = mul i64 [[IN0HI]], [[IN1]] -; CHECK-NEXT: [[M00:%.*]] = mul nuw i64 [[IN1LO]], [[IN0LO]] -; CHECK-NEXT: [[ADDC:%.*]] = add i64 [[M01]], [[M10]] -; CHECK-NEXT: [[SHL:%.*]] = shl i64 [[ADDC]], 32 -; CHECK-NEXT: [[ADDC9:%.*]] = add i64 [[M00]], [[SHL]] +; CHECK-NEXT: [[ADDC9:%.*]] = mul i64 [[IN0:%.*]], [[IN1:%.*]] ; CHECK-NEXT: ret i64 [[ADDC9]] ; %In0Lo = and i64 %in0, 4294967295 @@ -1796,16 +1724,7 @@ define i64 @mul64_low_A2_B0(i64 noundef %in0, i64 noundef %in1) { ; CHECK-LABEL: @mul64_low_A2_B0( -; CHECK-NEXT: [[IN0LO:%.*]] = and i64 [[IN0:%.*]], 4294967295 -; CHECK-NEXT: [[IN0HI:%.*]] = lshr i64 [[IN0]], 32 -; CHECK-NEXT: [[IN1LO:%.*]] = and i64 [[IN1:%.*]], 4294967295 -; CHECK-NEXT: [[IN1HI:%.*]] = lshr i64 [[IN1]], 32 -; CHECK-NEXT: [[M10:%.*]] = mul i64 [[IN1HI]], [[IN0]] -; CHECK-NEXT: [[M01:%.*]] = mul i64 [[IN0HI]], [[IN1]] -; CHECK-NEXT: [[M00:%.*]] = mul nuw i64 [[IN1LO]], [[IN0LO]] -; CHECK-NEXT: [[ADDC:%.*]] = add i64 [[M10]], [[M01]] -; CHECK-NEXT: [[SHL:%.*]] = shl i64 [[ADDC]], 32 -; CHECK-NEXT: [[ADDC9:%.*]] = add i64 [[SHL]], [[M00]] +; CHECK-NEXT: [[ADDC9:%.*]] = mul i64 [[IN0:%.*]], [[IN1:%.*]] ; CHECK-NEXT: ret i64 [[ADDC9]] ; %In0Lo = and i64 %in0, 4294967295 @@ -1823,16 +1742,7 @@ define i64 @mul64_low_A2_B1(i64 noundef %in0, i64 noundef %in1) { ; CHECK-LABEL: @mul64_low_A2_B1( -; CHECK-NEXT: [[IN0LO:%.*]] = and i64 [[IN0:%.*]], 4294967295 -; CHECK-NEXT: [[IN0HI:%.*]] = lshr i64 [[IN0]], 32 -; CHECK-NEXT: [[IN1LO:%.*]] = and i64 [[IN1:%.*]], 4294967295 -; CHECK-NEXT: [[IN1HI:%.*]] = lshr i64 [[IN1]], 32 -; CHECK-NEXT: [[M10:%.*]] = mul i64 [[IN1HI]], [[IN0]] -; CHECK-NEXT: [[M01:%.*]] = mul i64 [[IN0HI]], [[IN1]] -; CHECK-NEXT: [[M00:%.*]] = mul nuw i64 [[IN1LO]], [[IN0LO]] -; CHECK-NEXT: [[ADDC:%.*]] = add i64 [[M10]], [[M01]] -; CHECK-NEXT: [[SHL:%.*]] = shl i64 [[ADDC]], 32 -; CHECK-NEXT: [[ADDC9:%.*]] = add i64 [[M00]], [[SHL]] +; CHECK-NEXT: [[ADDC9:%.*]] = mul i64 [[IN0:%.*]], [[IN1:%.*]] ; CHECK-NEXT: ret i64 [[ADDC9]] ; %In0Lo = and i64 %in0, 4294967295 @@ -1850,16 +1760,7 @@ define i64 @mul64_low_A2_B2(i64 noundef %in0, i64 noundef %in1) { ; CHECK-LABEL: @mul64_low_A2_B2( -; CHECK-NEXT: [[IN0LO:%.*]] = and i64 [[IN0:%.*]], 4294967295 -; CHECK-NEXT: [[IN0HI:%.*]] = lshr i64 [[IN0]], 32 -; CHECK-NEXT: [[IN1LO:%.*]] = and i64 [[IN1:%.*]], 4294967295 -; CHECK-NEXT: [[IN1HI:%.*]] = lshr i64 [[IN1]], 32 -; CHECK-NEXT: [[M10:%.*]] = mul i64 [[IN1HI]], [[IN0]] -; CHECK-NEXT: [[M01:%.*]] = mul i64 [[IN0HI]], [[IN1]] -; CHECK-NEXT: [[M00:%.*]] = mul nuw i64 [[IN1LO]], [[IN0LO]] -; CHECK-NEXT: [[ADDC:%.*]] = add i64 [[M01]], [[M10]] -; CHECK-NEXT: [[SHL:%.*]] = shl i64 [[ADDC]], 32 -; CHECK-NEXT: [[ADDC9:%.*]] = add i64 [[SHL]], [[M00]] +; CHECK-NEXT: [[ADDC9:%.*]] = mul i64 [[IN0:%.*]], [[IN1:%.*]] ; CHECK-NEXT: ret i64 [[ADDC9]] ; %In0Lo = and i64 %in0, 4294967295 @@ -1877,16 +1778,7 @@ define i64 @mul64_low_A2_B3(i64 noundef %in0, i64 noundef %in1) { ; CHECK-LABEL: @mul64_low_A2_B3( -; CHECK-NEXT: [[IN0LO:%.*]] = and i64 [[IN0:%.*]], 4294967295 -; CHECK-NEXT: [[IN0HI:%.*]] = lshr i64 [[IN0]], 32 -; CHECK-NEXT: [[IN1LO:%.*]] = and i64 [[IN1:%.*]], 4294967295 -; CHECK-NEXT: [[IN1HI:%.*]] = lshr i64 [[IN1]], 32 -; CHECK-NEXT: [[M10:%.*]] = mul i64 [[IN1HI]], [[IN0]] -; CHECK-NEXT: [[M01:%.*]] = mul i64 [[IN0HI]], [[IN1]] -; CHECK-NEXT: [[M00:%.*]] = mul nuw i64 [[IN1LO]], [[IN0LO]] -; CHECK-NEXT: [[ADDC:%.*]] = add i64 [[M01]], [[M10]] -; CHECK-NEXT: [[SHL:%.*]] = shl i64 [[ADDC]], 32 -; CHECK-NEXT: [[ADDC9:%.*]] = add i64 [[M00]], [[SHL]] +; CHECK-NEXT: [[ADDC9:%.*]] = mul i64 [[IN0:%.*]], [[IN1:%.*]] ; CHECK-NEXT: ret i64 [[ADDC9]] ; %In0Lo = and i64 %in0, 4294967295 @@ -1904,16 +1796,7 @@ define i64 @mul64_low_A3_B0(i64 noundef %in0, i64 noundef %in1) { ; CHECK-LABEL: @mul64_low_A3_B0( -; CHECK-NEXT: [[IN0LO:%.*]] = and i64 [[IN0:%.*]], 4294967295 -; CHECK-NEXT: [[IN0HI:%.*]] = lshr i64 [[IN0]], 32 -; CHECK-NEXT: [[IN1LO:%.*]] = and i64 [[IN1:%.*]], 4294967295 -; CHECK-NEXT: [[IN1HI:%.*]] = lshr i64 [[IN1]], 32 -; CHECK-NEXT: [[M10:%.*]] = mul i64 [[IN1HI]], [[IN0]] -; CHECK-NEXT: [[M01:%.*]] = mul i64 [[IN0HI]], [[IN1]] -; CHECK-NEXT: [[M00:%.*]] = mul nuw i64 [[IN1LO]], [[IN0LO]] -; CHECK-NEXT: [[ADDC:%.*]] = add i64 [[M10]], [[M01]] -; CHECK-NEXT: [[SHL:%.*]] = shl i64 [[ADDC]], 32 -; CHECK-NEXT: [[ADDC9:%.*]] = add i64 [[SHL]], [[M00]] +; CHECK-NEXT: [[ADDC9:%.*]] = mul i64 [[IN0:%.*]], [[IN1:%.*]] ; CHECK-NEXT: ret i64 [[ADDC9]] ; %In0Lo = and i64 %in0, 4294967295 @@ -1931,16 +1814,7 @@ define i64 @mul64_low_A3_B1(i64 noundef %in0, i64 noundef %in1) { ; CHECK-LABEL: @mul64_low_A3_B1( -; CHECK-NEXT: [[IN0LO:%.*]] = and i64 [[IN0:%.*]], 4294967295 -; CHECK-NEXT: [[IN0HI:%.*]] = lshr i64 [[IN0]], 32 -; CHECK-NEXT: [[IN1LO:%.*]] = and i64 [[IN1:%.*]], 4294967295 -; CHECK-NEXT: [[IN1HI:%.*]] = lshr i64 [[IN1]], 32 -; CHECK-NEXT: [[M10:%.*]] = mul i64 [[IN1HI]], [[IN0]] -; CHECK-NEXT: [[M01:%.*]] = mul i64 [[IN0HI]], [[IN1]] -; CHECK-NEXT: [[M00:%.*]] = mul nuw i64 [[IN1LO]], [[IN0LO]] -; CHECK-NEXT: [[ADDC:%.*]] = add i64 [[M10]], [[M01]] -; CHECK-NEXT: [[SHL:%.*]] = shl i64 [[ADDC]], 32 -; CHECK-NEXT: [[ADDC9:%.*]] = add i64 [[M00]], [[SHL]] +; CHECK-NEXT: [[ADDC9:%.*]] = mul i64 [[IN0:%.*]], [[IN1:%.*]] ; CHECK-NEXT: ret i64 [[ADDC9]] ; %In0Lo = and i64 %in0, 4294967295 @@ -1958,16 +1832,7 @@ define i64 @mul64_low_A3_B2(i64 noundef %in0, i64 noundef %in1) { ; CHECK-LABEL: @mul64_low_A3_B2( -; CHECK-NEXT: [[IN0LO:%.*]] = and i64 [[IN0:%.*]], 4294967295 -; CHECK-NEXT: [[IN0HI:%.*]] = lshr i64 [[IN0]], 32 -; CHECK-NEXT: [[IN1LO:%.*]] = and i64 [[IN1:%.*]], 4294967295 -; CHECK-NEXT: [[IN1HI:%.*]] = lshr i64 [[IN1]], 32 -; CHECK-NEXT: [[M10:%.*]] = mul i64 [[IN1HI]], [[IN0]] -; CHECK-NEXT: [[M01:%.*]] = mul i64 [[IN0HI]], [[IN1]] -; CHECK-NEXT: [[M00:%.*]] = mul nuw i64 [[IN1LO]], [[IN0LO]] -; CHECK-NEXT: [[ADDC:%.*]] = add i64 [[M01]], [[M10]] -; CHECK-NEXT: [[SHL:%.*]] = shl i64 [[ADDC]], 32 -; CHECK-NEXT: [[ADDC9:%.*]] = add i64 [[SHL]], [[M00]] +; CHECK-NEXT: [[ADDC9:%.*]] = mul i64 [[IN0:%.*]], [[IN1:%.*]] ; CHECK-NEXT: ret i64 [[ADDC9]] ; %In0Lo = and i64 %in0, 4294967295 @@ -1985,16 +1850,7 @@ define i64 @mul64_low_A3_B3(i64 noundef %in0, i64 noundef %in1) { ; CHECK-LABEL: @mul64_low_A3_B3( -; CHECK-NEXT: [[IN0LO:%.*]] = and i64 [[IN0:%.*]], 4294967295 -; CHECK-NEXT: [[IN0HI:%.*]] = lshr i64 [[IN0]], 32 -; CHECK-NEXT: [[IN1LO:%.*]] = and i64 [[IN1:%.*]], 4294967295 -; CHECK-NEXT: [[IN1HI:%.*]] = lshr i64 [[IN1]], 32 -; CHECK-NEXT: [[M10:%.*]] = mul i64 [[IN1HI]], [[IN0]] -; CHECK-NEXT: [[M01:%.*]] = mul i64 [[IN0HI]], [[IN1]] -; CHECK-NEXT: [[M00:%.*]] = mul nuw i64 [[IN1LO]], [[IN0LO]] -; CHECK-NEXT: [[ADDC:%.*]] = add i64 [[M01]], [[M10]] -; CHECK-NEXT: [[SHL:%.*]] = shl i64 [[ADDC]], 32 -; CHECK-NEXT: [[ADDC9:%.*]] = add i64 [[M00]], [[SHL]] +; CHECK-NEXT: [[ADDC9:%.*]] = mul i64 [[IN0:%.*]], [[IN1:%.*]] ; CHECK-NEXT: ret i64 [[ADDC9]] ; %In0Lo = and i64 %in0, 4294967295 @@ -2018,11 +1874,9 @@ ; CHECK-NEXT: [[IN1HI:%.*]] = lshr i32 [[IN1]], 16 ; CHECK-NEXT: [[M10:%.*]] = mul nuw i32 [[IN1HI]], [[IN0LO]] ; CHECK-NEXT: [[M01:%.*]] = mul nuw i32 [[IN1LO]], [[IN0HI]] -; CHECK-NEXT: [[M00:%.*]] = mul nuw i32 [[IN1LO]], [[IN0LO]] ; CHECK-NEXT: [[ADDC:%.*]] = add i32 [[M10]], [[M01]] ; CHECK-NEXT: call void @use32(i32 [[ADDC]]) -; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[ADDC]], 16 -; CHECK-NEXT: [[ADDC9:%.*]] = add i32 [[SHL]], [[M00]] +; CHECK-NEXT: [[ADDC9:%.*]] = mul i32 [[IN0]], [[IN1]] ; CHECK-NEXT: ret i32 [[ADDC9]] ; %In0Lo = and i32 %in0, 65535 @@ -2041,16 +1895,7 @@ define i32 @mul32_low(i32 noundef %in0, i32 noundef %in1) { ; CHECK-LABEL: @mul32_low( -; CHECK-NEXT: [[IN0LO:%.*]] = and i32 [[IN0:%.*]], 65535 -; CHECK-NEXT: [[IN0HI:%.*]] = lshr i32 [[IN0]], 16 -; CHECK-NEXT: [[IN1LO:%.*]] = and i32 [[IN1:%.*]], 65535 -; CHECK-NEXT: [[IN1HI:%.*]] = lshr i32 [[IN1]], 16 -; CHECK-NEXT: [[M10:%.*]] = mul i32 [[IN1HI]], [[IN0]] -; CHECK-NEXT: [[M01:%.*]] = mul i32 [[IN0HI]], [[IN1]] -; CHECK-NEXT: [[M00:%.*]] = mul nuw i32 [[IN1LO]], [[IN0LO]] -; CHECK-NEXT: [[ADDC:%.*]] = add i32 [[M10]], [[M01]] -; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[ADDC]], 16 -; CHECK-NEXT: [[ADDC9:%.*]] = add i32 [[SHL]], [[M00]] +; CHECK-NEXT: [[ADDC9:%.*]] = mul i32 [[IN0:%.*]], [[IN1:%.*]] ; CHECK-NEXT: ret i32 [[ADDC9]] ; %In0Lo = and i32 %in0, 65535 @@ -2068,16 +1913,7 @@ define i16 @mul16_low(i16 %in0, i16 %in1) { ; CHECK-LABEL: @mul16_low( -; CHECK-NEXT: [[IN0LO:%.*]] = and i16 [[IN0:%.*]], 255 -; CHECK-NEXT: [[IN0HI:%.*]] = lshr i16 [[IN0]], 8 -; CHECK-NEXT: [[IN1LO:%.*]] = and i16 [[IN1:%.*]], 255 -; CHECK-NEXT: [[IN1HI:%.*]] = lshr i16 [[IN1]], 8 -; CHECK-NEXT: [[M10:%.*]] = mul i16 [[IN1HI]], [[IN0]] -; CHECK-NEXT: [[M01:%.*]] = mul i16 [[IN0HI]], [[IN1]] -; CHECK-NEXT: [[M00:%.*]] = mul nuw i16 [[IN1LO]], [[IN0LO]] -; CHECK-NEXT: [[ADDC:%.*]] = add i16 [[M10]], [[M01]] -; CHECK-NEXT: [[SHL:%.*]] = shl i16 [[ADDC]], 8 -; CHECK-NEXT: [[ADDC9:%.*]] = add i16 [[SHL]], [[M00]] +; CHECK-NEXT: [[ADDC9:%.*]] = mul i16 [[IN0:%.*]], [[IN1:%.*]] ; CHECK-NEXT: ret i16 [[ADDC9]] ; %In0Lo = and i16 %in0, 255 @@ -2096,16 +1932,7 @@ ; https://alive2.llvm.org/ce/z/2BqKLt define i8 @mul8_low(i8 %in0, i8 %in1) { ; CHECK-LABEL: @mul8_low( -; CHECK-NEXT: [[IN0LO:%.*]] = and i8 [[IN0:%.*]], 15 -; CHECK-NEXT: [[IN0HI:%.*]] = lshr i8 [[IN0]], 4 -; CHECK-NEXT: [[IN1LO:%.*]] = and i8 [[IN1:%.*]], 15 -; CHECK-NEXT: [[IN1HI:%.*]] = lshr i8 [[IN1]], 4 -; CHECK-NEXT: [[M10:%.*]] = mul i8 [[IN1HI]], [[IN0]] -; CHECK-NEXT: [[M01:%.*]] = mul i8 [[IN0HI]], [[IN1]] -; CHECK-NEXT: [[M00:%.*]] = mul nuw i8 [[IN1LO]], [[IN0LO]] -; CHECK-NEXT: [[ADDC:%.*]] = add i8 [[M10]], [[M01]] -; CHECK-NEXT: [[SHL:%.*]] = shl i8 [[ADDC]], 4 -; CHECK-NEXT: [[ADDC9:%.*]] = add i8 [[SHL]], [[M00]] +; CHECK-NEXT: [[ADDC9:%.*]] = mul i8 [[IN0:%.*]], [[IN1:%.*]] ; CHECK-NEXT: ret i8 [[ADDC9]] ; %In0Lo = and i8 %in0, 15 @@ -2179,16 +2006,7 @@ define i128 @mul128_low(i128 %in0, i128 %in1) { ; CHECK-LABEL: @mul128_low( -; CHECK-NEXT: [[IN0LO:%.*]] = and i128 [[IN0:%.*]], 18446744073709551615 -; CHECK-NEXT: [[IN0HI:%.*]] = lshr i128 [[IN0]], 64 -; CHECK-NEXT: [[IN1LO:%.*]] = and i128 [[IN1:%.*]], 18446744073709551615 -; CHECK-NEXT: [[IN1HI:%.*]] = lshr i128 [[IN1]], 64 -; CHECK-NEXT: [[M10:%.*]] = mul i128 [[IN1HI]], [[IN0]] -; CHECK-NEXT: [[M01:%.*]] = mul i128 [[IN0HI]], [[IN1]] -; CHECK-NEXT: [[M00:%.*]] = mul nuw i128 [[IN1LO]], [[IN0LO]] -; CHECK-NEXT: [[ADDC:%.*]] = add i128 [[M10]], [[M01]] -; CHECK-NEXT: [[SHL:%.*]] = shl i128 [[ADDC]], 64 -; CHECK-NEXT: [[ADDC9:%.*]] = add i128 [[SHL]], [[M00]] +; CHECK-NEXT: [[ADDC9:%.*]] = mul i128 [[IN0:%.*]], [[IN1:%.*]] ; CHECK-NEXT: ret i128 [[ADDC9]] ; %In0Lo = and i128 %in0, 18446744073709551615