llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-llvm-transforms Author: Ricardo Jesus (rj-jesus) <details> <summary>Changes</summary> The source values must be equally extended to double their width. The result is sign/zero-extended for an arithmetic/logical shift. This is a simplified version of DAGCombiner's combineShiftToMULH. --- Patch is 46.39 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/224311.diff 9 Files Affected: - (modified) clang/test/CodeGen/X86/ms-x86-intrinsics.c (+2-2) - (modified) llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp (+19) - (modified) llvm/test/Transforms/AggressiveInstCombine/umulh_carry.ll (+7-35) - (modified) llvm/test/Transforms/AggressiveInstCombine/umulh_carry4.ll (+16-80) - (modified) llvm/test/Transforms/AggressiveInstCombine/umulh_ladder.ll (+10-50) - (modified) llvm/test/Transforms/AggressiveInstCombine/umulh_ladder4.ll (+5-25) - (added) llvm/test/Transforms/InstCombine/mulh.ll (+418) - (modified) llvm/test/Transforms/InstCombine/trunc-inseltpoison.ll (+3-5) - (modified) llvm/test/Transforms/InstCombine/trunc.ll (+3-5) ``````````diff diff --git a/clang/test/CodeGen/X86/ms-x86-intrinsics.c b/clang/test/CodeGen/X86/ms-x86-intrinsics.c index 34cf690e6d5da..9099b56e50d45 100644 --- a/clang/test/CodeGen/X86/ms-x86-intrinsics.c +++ b/clang/test/CodeGen/X86/ms-x86-intrinsics.c @@ -158,13 +158,13 @@ __int64 test__mulh(__int64 a, __int64 b) { return __mulh(a, b); } // CHECK-X64-LABEL: define dso_local range(i64 -4611686018427387904, 4611686018427387905) i64 @test__mulh(i64 noundef %a, i64 noundef %b) -// CHECK-X64: = mul nsw i128 % +// CHECK-X64: = tail call i64 @llvm.smulh.i64(i64 %a, i64 %b) unsigned __int64 test__umulh(unsigned __int64 a, unsigned __int64 b) { return __umulh(a, b); } // CHECK-X64-LABEL: define dso_local range(i64 0, -1) i64 @test__umulh(i64 noundef %a, i64 noundef %b) -// CHECK-X64: = mul nuw i128 % +// CHECK-X64: = tail call i64 @llvm.umulh.i64(i64 %a, i64 %b) __int64 test_mul128(__int64 Multiplier, __int64 Multiplicand, diff --git a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp index 7e32abcd6e9ba..a8dc034588ecf 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp @@ -923,6 +923,25 @@ Instruction *InstCombinerImpl::FoldShiftByConstant(Value *Op0, Constant *C1, return CastInst::Create(ExtOpcode, Cmp, Ty); } + // (ext(A) * ext(B)) >> (Width / 2) --> ext([su]mulh(A, B)) + // A and B must be equally extended to double their original width. + // The result is sign/zero-extended for an arithmetic/logical shift. + Value *A, *B; + Instruction *ExtA, *ExtB; + if (!IsLeftShift && match(C1, m_SpecificIntAllowPoison(TypeBits / 2)) && + match(Op0, + m_OneUse(m_Mul(m_Instruction(ExtA, m_ZExtOrSExt(m_Value(A))), + m_Instruction(ExtB, m_ZExtOrSExt(m_Value(B)))))) && + ExtA->getOpcode() == ExtB->getOpcode() && A->getType() == B->getType() && + TypeBits == 2 * A->getType()->getScalarSizeInBits()) { + auto IID = ExtA->getOpcode() == Instruction::SExt ? Intrinsic::smulh + : Intrinsic::umulh; + Value *MulHigh = Builder.CreateBinaryIntrinsic(IID, A, B); + auto ExtOp = I.getOpcode() == Instruction::LShr ? Instruction::ZExt + : Instruction::SExt; + return CastInst::Create(ExtOp, MulHigh, Ty); + } + const APInt *Op1C; if (!match(C1, m_APInt(Op1C))) return nullptr; diff --git a/llvm/test/Transforms/AggressiveInstCombine/umulh_carry.ll b/llvm/test/Transforms/AggressiveInstCombine/umulh_carry.ll index b78095cac0df9..8a50435dde27a 100644 --- a/llvm/test/Transforms/AggressiveInstCombine/umulh_carry.ll +++ b/llvm/test/Transforms/AggressiveInstCombine/umulh_carry.ll @@ -6,11 +6,7 @@ define i32 @mul_carry(i32 %x, i32 %y) { ; CHECK-LABEL: define i32 @mul_carry( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { ; CHECK-NEXT: [[ENTRY:.*:]] -; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[X]] to i64 -; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[Y]] to i64 -; CHECK-NEXT: [[TMP2:%.*]] = mul nuw i64 [[TMP0]], [[TMP1]] -; CHECK-NEXT: [[TMP3:%.*]] = lshr i64 [[TMP2]], 32 -; CHECK-NEXT: [[ADD11:%.*]] = trunc nuw i64 [[TMP3]] to i32 +; CHECK-NEXT: [[ADD11:%.*]] = call i32 @llvm.umulh.i32(i32 [[X]], i32 [[Y]]) ; CHECK-NEXT: ret i32 [[ADD11]] ; entry: @@ -38,11 +34,7 @@ define i128 @mul_carry_i128(i128 %x, i128 %y) { ; CHECK-LABEL: define i128 @mul_carry_i128( ; CHECK-SAME: i128 [[X:%.*]], i128 [[Y:%.*]]) { ; CHECK-NEXT: [[ENTRY:.*:]] -; CHECK-NEXT: [[TMP0:%.*]] = zext i128 [[X]] to i256 -; CHECK-NEXT: [[TMP1:%.*]] = zext i128 [[Y]] to i256 -; CHECK-NEXT: [[TMP2:%.*]] = mul nuw i256 [[TMP0]], [[TMP1]] -; CHECK-NEXT: [[TMP3:%.*]] = lshr i256 [[TMP2]], 128 -; CHECK-NEXT: [[ADD11:%.*]] = trunc nuw i256 [[TMP3]] to i128 +; CHECK-NEXT: [[ADD11:%.*]] = call i128 @llvm.umulh.i128(i128 [[X]], i128 [[Y]]) ; CHECK-NEXT: ret i128 [[ADD11]] ; entry: @@ -70,11 +62,7 @@ define <4 x i32> @mul_carry_v4i32(<4 x i32> %x, <4 x i32> %y) { ; CHECK-LABEL: define <4 x i32> @mul_carry_v4i32( ; CHECK-SAME: <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]]) { ; CHECK-NEXT: [[ENTRY:.*:]] -; CHECK-NEXT: [[TMP0:%.*]] = zext <4 x i32> [[X]] to <4 x i64> -; CHECK-NEXT: [[TMP1:%.*]] = zext <4 x i32> [[Y]] to <4 x i64> -; CHECK-NEXT: [[TMP2:%.*]] = mul nuw <4 x i64> [[TMP0]], [[TMP1]] -; CHECK-NEXT: [[TMP3:%.*]] = lshr <4 x i64> [[TMP2]], splat (i64 32) -; CHECK-NEXT: [[ADD11:%.*]] = trunc nuw <4 x i64> [[TMP3]] to <4 x i32> +; CHECK-NEXT: [[ADD11:%.*]] = call <4 x i32> @llvm.umulh.v4i32(<4 x i32> [[X]], <4 x i32> [[Y]]) ; CHECK-NEXT: ret <4 x i32> [[ADD11]] ; entry: @@ -102,11 +90,7 @@ define i32 @mul_carry_xlyh(i32 %x, i32 %y) { ; CHECK-LABEL: define i32 @mul_carry_xlyh( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { ; CHECK-NEXT: [[ENTRY:.*:]] -; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[Y]] to i64 -; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[X]] to i64 -; CHECK-NEXT: [[TMP2:%.*]] = mul nuw i64 [[TMP0]], [[TMP1]] -; CHECK-NEXT: [[TMP3:%.*]] = lshr i64 [[TMP2]], 32 -; CHECK-NEXT: [[ADD11:%.*]] = trunc nuw i64 [[TMP3]] to i32 +; CHECK-NEXT: [[ADD11:%.*]] = call i32 @llvm.umulh.i32(i32 [[Y]], i32 [[X]]) ; CHECK-NEXT: ret i32 [[ADD11]] ; entry: @@ -133,11 +117,7 @@ define i32 @mul_carry_comm(i32 %x, i32 %y) { ; CHECK-LABEL: define i32 @mul_carry_comm( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { ; CHECK-NEXT: [[ENTRY:.*:]] -; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[X]] to i64 -; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[Y]] to i64 -; CHECK-NEXT: [[TMP2:%.*]] = mul nuw i64 [[TMP0]], [[TMP1]] -; CHECK-NEXT: [[TMP3:%.*]] = lshr i64 [[TMP2]], 32 -; CHECK-NEXT: [[ADD11:%.*]] = trunc nuw i64 [[TMP3]] to i32 +; CHECK-NEXT: [[ADD11:%.*]] = call i32 @llvm.umulh.i32(i32 [[X]], i32 [[Y]]) ; CHECK-NEXT: ret i32 [[ADD11]] ; entry: @@ -469,11 +449,7 @@ define i32 @mul_carry_use_llh(i32 %x, i32 %y) { ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[Y]], 65535 ; CHECK-NEXT: [[ADD6:%.*]] = mul nuw i32 [[AND]], [[AND2]] ; CHECK-NEXT: [[SHR10:%.*]] = lshr i32 [[ADD6]], 16 -; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[X]] to i64 -; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[Y]] to i64 -; CHECK-NEXT: [[TMP2:%.*]] = mul nuw i64 [[TMP0]], [[TMP1]] -; CHECK-NEXT: [[TMP3:%.*]] = lshr i64 [[TMP2]], 32 -; CHECK-NEXT: [[ADD11:%.*]] = trunc nuw i64 [[TMP3]] to i32 +; CHECK-NEXT: [[ADD11:%.*]] = call i32 @llvm.umulh.i32(i32 [[X]], i32 [[Y]]) ; CHECK-NEXT: call void (...) @llvm.fake.use(i32 [[SHR10]]) ; CHECK-NEXT: ret i32 [[ADD11]] ; @@ -505,11 +481,7 @@ define i32 @mul_carry_use_mulll(i32 %x, i32 %y) { ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], 65535 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[Y]], 65535 ; CHECK-NEXT: [[MUL4:%.*]] = mul nuw i32 [[AND]], [[AND2]] -; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[X]] to i64 -; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[Y]] to i64 -; CHECK-NEXT: [[TMP2:%.*]] = mul nuw i64 [[TMP0]], [[TMP1]] -; CHECK-NEXT: [[TMP3:%.*]] = lshr i64 [[TMP2]], 32 -; CHECK-NEXT: [[ADD11:%.*]] = trunc nuw i64 [[TMP3]] to i32 +; CHECK-NEXT: [[ADD11:%.*]] = call i32 @llvm.umulh.i32(i32 [[X]], i32 [[Y]]) ; CHECK-NEXT: call void (...) @llvm.fake.use(i32 [[MUL4]]) ; CHECK-NEXT: ret i32 [[ADD11]] ; diff --git a/llvm/test/Transforms/AggressiveInstCombine/umulh_carry4.ll b/llvm/test/Transforms/AggressiveInstCombine/umulh_carry4.ll index fa21721f17762..ba843073dc7d0 100644 --- a/llvm/test/Transforms/AggressiveInstCombine/umulh_carry4.ll +++ b/llvm/test/Transforms/AggressiveInstCombine/umulh_carry4.ll @@ -5,11 +5,7 @@ define i64 @umulh(i64 %x, i64 %y) { ; CHECK-LABEL: define i64 @umulh( ; CHECK-SAME: i64 [[X:%.*]], i64 [[Y:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = zext i64 [[X]] to i128 -; CHECK-NEXT: [[TMP2:%.*]] = zext i64 [[Y]] to i128 -; CHECK-NEXT: [[TMP3:%.*]] = mul nuw i128 [[TMP1]], [[TMP2]] -; CHECK-NEXT: [[TMP5:%.*]] = lshr i128 [[TMP3]], 64 -; CHECK-NEXT: [[TMP4:%.*]] = trunc nuw i128 [[TMP5]] to i64 +; CHECK-NEXT: [[TMP4:%.*]] = call i64 @llvm.umulh.i64(i64 [[X]], i64 [[Y]]) ; CHECK-NEXT: ret i64 [[TMP4]] ; ; Extract low and high 32 bits @@ -56,11 +52,7 @@ define i64 @umulh(i64 %x, i64 %y) { define i64 @umulh__commuted(i64 %x, i64 %y) { ; CHECK-LABEL: define i64 @umulh__commuted( ; CHECK-SAME: i64 [[X:%.*]], i64 [[Y:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = zext i64 [[X]] to i128 -; CHECK-NEXT: [[TMP2:%.*]] = zext i64 [[Y]] to i128 -; CHECK-NEXT: [[TMP3:%.*]] = mul nuw i128 [[TMP1]], [[TMP2]] -; CHECK-NEXT: [[TMP5:%.*]] = lshr i128 [[TMP3]], 64 -; CHECK-NEXT: [[TMP4:%.*]] = trunc nuw i128 [[TMP5]] to i64 +; CHECK-NEXT: [[TMP4:%.*]] = call i64 @llvm.umulh.i64(i64 [[X]], i64 [[Y]]) ; CHECK-NEXT: ret i64 [[TMP4]] ; ; Extract low and high 32 bits @@ -104,11 +96,7 @@ define i32 @mulh_src32(i32 %x, i32 %y) { ; Extract low and high 16 bits ; CHECK-LABEL: define i32 @mulh_src32( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[X]] to i64 -; CHECK-NEXT: [[TMP2:%.*]] = zext i32 [[Y]] to i64 -; CHECK-NEXT: [[TMP3:%.*]] = mul nuw i64 [[TMP1]], [[TMP2]] -; CHECK-NEXT: [[TMP4:%.*]] = lshr i64 [[TMP3]], 32 -; CHECK-NEXT: [[TMP5:%.*]] = trunc nuw i64 [[TMP4]] to i32 +; CHECK-NEXT: [[TMP5:%.*]] = call i32 @llvm.umulh.i32(i32 [[X]], i32 [[Y]]) ; CHECK-NEXT: ret i32 [[TMP5]] ; %x_lo = and i32 %x, u0xffff ; x & 0xffffffff @@ -151,11 +139,7 @@ define i128 @mulh_src128(i128 %x, i128 %y) { ; Extract low and high 64 bits ; CHECK-LABEL: define i128 @mulh_src128( ; CHECK-SAME: i128 [[X:%.*]], i128 [[Y:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = zext i128 [[X]] to i256 -; CHECK-NEXT: [[TMP2:%.*]] = zext i128 [[Y]] to i256 -; CHECK-NEXT: [[TMP3:%.*]] = mul nuw i256 [[TMP1]], [[TMP2]] -; CHECK-NEXT: [[TMP4:%.*]] = lshr i256 [[TMP3]], 128 -; CHECK-NEXT: [[HW64:%.*]] = trunc nuw i256 [[TMP4]] to i128 +; CHECK-NEXT: [[HW64:%.*]] = call i128 @llvm.umulh.i128(i128 [[X]], i128 [[Y]]) ; CHECK-NEXT: ret i128 [[HW64]] ; %x_lo = and i128 %x, u0xffffffffffffffff ; x & 0xffffffff @@ -198,11 +182,7 @@ define <2 x i32> @mulh_v2i32(<2 x i32> %x, <2 x i32> %y) { ; Extract low and high 16 bits ; CHECK-LABEL: define <2 x i32> @mulh_v2i32( ; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = zext <2 x i32> [[X]] to <2 x i64> -; CHECK-NEXT: [[TMP2:%.*]] = zext <2 x i32> [[Y]] to <2 x i64> -; CHECK-NEXT: [[TMP3:%.*]] = mul nuw <2 x i64> [[TMP1]], [[TMP2]] -; CHECK-NEXT: [[TMP4:%.*]] = lshr <2 x i64> [[TMP3]], splat (i64 32) -; CHECK-NEXT: [[HW64:%.*]] = trunc nuw <2 x i64> [[TMP4]] to <2 x i32> +; CHECK-NEXT: [[HW64:%.*]] = call <2 x i32> @llvm.umulh.v2i32(<2 x i32> [[X]], <2 x i32> [[Y]]) ; CHECK-NEXT: ret <2 x i32> [[HW64]] ; %x_lo = and <2 x i32> %x, <i32 u0xffff, i32 u0xffff> @@ -245,11 +225,7 @@ define <2 x i32> @mulh_v2i32(<2 x i32> %x, <2 x i32> %y) { define void @full_mul_int128(i64 %x, i64 %y, ptr %p) { ; CHECK-LABEL: define void @full_mul_int128( ; CHECK-SAME: i64 [[X:%.*]], i64 [[Y:%.*]], ptr [[P:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = zext i64 [[X]] to i128 -; CHECK-NEXT: [[TMP2:%.*]] = zext i64 [[Y]] to i128 -; CHECK-NEXT: [[TMP3:%.*]] = mul nuw i128 [[TMP1]], [[TMP2]] -; CHECK-NEXT: [[TMP5:%.*]] = lshr i128 [[TMP3]], 64 -; CHECK-NEXT: [[TMP4:%.*]] = trunc nuw i128 [[TMP5]] to i64 +; CHECK-NEXT: [[TMP4:%.*]] = call i64 @llvm.umulh.i64(i64 [[X]], i64 [[Y]]) ; CHECK-NEXT: [[HI_PTR:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 ; CHECK-NEXT: store i64 [[TMP4]], ptr [[HI_PTR]], align 8 ; CHECK-NEXT: [[TMP8:%.*]] = mul i64 [[X]], [[Y]] @@ -745,11 +721,7 @@ define i64 @umulh__mul_use__x_lo(i64 %x, i64 %y) { ; CHECK-SAME: i64 [[X:%.*]], i64 [[Y:%.*]]) { ; CHECK-NEXT: [[X_LO:%.*]] = and i64 [[X]], 4294967295 ; CHECK-NEXT: call void (...) @llvm.fake.use(i64 [[X_LO]]) -; CHECK-NEXT: [[TMP1:%.*]] = zext i64 [[X]] to i128 -; CHECK-NEXT: [[TMP2:%.*]] = zext i64 [[Y]] to i128 -; CHECK-NEXT: [[TMP3:%.*]] = mul nuw i128 [[TMP1]], [[TMP2]] -; CHECK-NEXT: [[TMP4:%.*]] = lshr i128 [[TMP3]], 64 -; CHECK-NEXT: [[HW64:%.*]] = trunc nuw i128 [[TMP4]] to i64 +; CHECK-NEXT: [[HW64:%.*]] = call i64 @llvm.umulh.i64(i64 [[X]], i64 [[Y]]) ; CHECK-NEXT: ret i64 [[HW64]] ; ; Extract low and high 32 bits @@ -796,11 +768,7 @@ define i64 @umulh__mul_use__y_hi(i64 %x, i64 %y) { ; CHECK-SAME: i64 [[X:%.*]], i64 [[Y:%.*]]) { ; CHECK-NEXT: [[Y_HI:%.*]] = lshr i64 [[Y]], 32 ; CHECK-NEXT: call void (...) @llvm.fake.use(i64 [[Y_HI]]) -; CHECK-NEXT: [[TMP1:%.*]] = zext i64 [[X]] to i128 -; CHECK-NEXT: [[TMP2:%.*]] = zext i64 [[Y]] to i128 -; CHECK-NEXT: [[TMP3:%.*]] = mul nuw i128 [[TMP1]], [[TMP2]] -; CHECK-NEXT: [[TMP4:%.*]] = lshr i128 [[TMP3]], 64 -; CHECK-NEXT: [[HW64:%.*]] = trunc nuw i128 [[TMP4]] to i64 +; CHECK-NEXT: [[HW64:%.*]] = call i64 @llvm.umulh.i64(i64 [[X]], i64 [[Y]]) ; CHECK-NEXT: ret i64 [[HW64]] ; ; Extract low and high 32 bits @@ -1044,11 +1012,7 @@ define i64 @umulh__mul_use__y_lo_x_lo(i64 %x, i64 %y) { ; CHECK-NEXT: [[Y_LO:%.*]] = and i64 [[Y]], 4294967295 ; CHECK-NEXT: [[Y_LO_X_LO:%.*]] = mul nuw i64 [[Y_LO]], [[X_LO]] ; CHECK-NEXT: call void (...) @llvm.fake.use(i64 [[Y_LO_X_LO]]) -; CHECK-NEXT: [[TMP1:%.*]] = zext i64 [[X]] to i128 -; CHECK-NEXT: [[TMP2:%.*]] = zext i64 [[Y]] to i128 -; CHECK-NEXT: [[TMP3:%.*]] = mul nuw i128 [[TMP1]], [[TMP2]] -; CHECK-NEXT: [[TMP4:%.*]] = lshr i128 [[TMP3]], 64 -; CHECK-NEXT: [[TMP5:%.*]] = trunc nuw i128 [[TMP4]] to i64 +; CHECK-NEXT: [[TMP5:%.*]] = call i64 @llvm.umulh.i64(i64 [[X]], i64 [[Y]]) ; CHECK-NEXT: ret i64 [[TMP5]] ; ; Extract low and high 32 bits @@ -1492,11 +1456,7 @@ define i64 @umulh__mul_use__low_accum(i64 %x, i64 %y) { ; CHECK-NEXT: [[CROSS_SUM_LO:%.*]] = and i64 [[CROSS_SUM]], 4294967295 ; CHECK-NEXT: [[LOW_ACCUM:%.*]] = add nuw nsw i64 [[CROSS_SUM_LO]], [[Y_LO_X_LO_HI]] ; CHECK-NEXT: call void (...) @llvm.fake.use(i64 [[LOW_ACCUM]]) -; CHECK-NEXT: [[TMP1:%.*]] = zext i64 [[X]] to i128 -; CHECK-NEXT: [[TMP2:%.*]] = zext i64 [[Y]] to i128 -; CHECK-NEXT: [[TMP3:%.*]] = mul nuw i128 [[TMP1]], [[TMP2]] -; CHECK-NEXT: [[TMP4:%.*]] = lshr i128 [[TMP3]], 64 -; CHECK-NEXT: [[TMP5:%.*]] = trunc nuw i128 [[TMP4]] to i64 +; CHECK-NEXT: [[TMP5:%.*]] = call i64 @llvm.umulh.i64(i64 [[X]], i64 [[Y]]) ; CHECK-NEXT: ret i64 [[TMP5]] ; ; Extract low and high 32 bits @@ -1736,11 +1696,7 @@ define void @full_mul_int128__mul_use__x_lo(i64 %x, i64 %y, ptr %p) { ; CHECK-SAME: i64 [[X:%.*]], i64 [[Y:%.*]], ptr [[P:%.*]]) { ; CHECK-NEXT: [[X_LO:%.*]] = and i64 [[X]], 4294967295 ; CHECK-NEXT: call void (...) @llvm.fake.use(i64 [[X_LO]]) -; CHECK-NEXT: [[TMP1:%.*]] = zext i64 [[X]] to i128 -; CHECK-NEXT: [[TMP2:%.*]] = zext i64 [[Y]] to i128 -; CHECK-NEXT: [[TMP3:%.*]] = mul nuw i128 [[TMP1]], [[TMP2]] -; CHECK-NEXT: [[TMP4:%.*]] = lshr i128 [[TMP3]], 64 -; CHECK-NEXT: [[HW64:%.*]] = trunc nuw i128 [[TMP4]] to i64 +; CHECK-NEXT: [[HW64:%.*]] = call i64 @llvm.umulh.i64(i64 [[X]], i64 [[Y]]) ; CHECK-NEXT: [[HI_PTR:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 ; CHECK-NEXT: store i64 [[HW64]], ptr [[HI_PTR]], align 8 ; CHECK-NEXT: [[LW64:%.*]] = mul i64 [[X]], [[Y]] @@ -1793,11 +1749,7 @@ define void @full_mul_int128__mul_use__y_lo(i64 %x, i64 %y, ptr %p) { ; CHECK-SAME: i64 [[X:%.*]], i64 [[Y:%.*]], ptr [[P:%.*]]) { ; CHECK-NEXT: [[Y_LO:%.*]] = and i64 [[Y]], 4294967295 ; CHECK-NEXT: call void (...) @llvm.fake.use(i64 [[Y_LO]]) -; CHECK-NEXT: [[TMP1:%.*]] = zext i64 [[X]] to i128 -; CHECK-NEXT: [[TMP2:%.*]] = zext i64 [[Y]] to i128 -; CHECK-NEXT: [[TMP3:%.*]] = mul nuw i128 [[TMP1]], [[TMP2]] -; CHECK-NEXT: [[TMP4:%.*]] = lshr i128 [[TMP3]], 64 -; CHECK-NEXT: [[HW64:%.*]] = trunc nuw i128 [[TMP4]] to i64 +; CHECK-NEXT: [[HW64:%.*]] = call i64 @llvm.umulh.i64(i64 [[X]], i64 [[Y]]) ; CHECK-NEXT: [[HI_PTR:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 ; CHECK-NEXT: store i64 [[HW64]], ptr [[HI_PTR]], align 8 ; CHECK-NEXT: [[LW64:%.*]] = mul i64 [[X]], [[Y]] @@ -1850,11 +1802,7 @@ define void @full_mul_int128__mul_use__x_hi(i64 %x, i64 %y, ptr %p) { ; CHECK-SAME: i64 [[X:%.*]], i64 [[Y:%.*]], ptr [[P:%.*]]) { ; CHECK-NEXT: [[X_HI:%.*]] = lshr i64 [[X]], 32 ; CHECK-NEXT: call void (...) @llvm.fake.use(i64 [[X_HI]]) -; CHECK-NEXT: [[TMP1:%.*]] = zext i64 [[X]] to i128 -; CHECK-NEXT: [[TMP2:%.*]] = zext i64 [[Y]] to i128 -; CHECK-NEXT: [[TMP3:%.*]] = mul nuw i128 [[TMP1]], [[TMP2]] -; CHECK-NEXT: [[TMP4:%.*]] = lshr i128 [[TMP3]], 64 -; CHECK-NEXT: [[HW64:%.*]] = trunc nuw i128 [[TMP4]] to i64 +; CHECK-NEXT: [[HW64:%.*]] = call i64 @llvm.umulh.i64(i64 [[X]], i64 [[Y]]) ; CHECK-NEXT: [[HI_PTR:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 ; CHECK-NEXT: store i64 [[HW64]], ptr [[HI_PTR]], align 8 ; CHECK-NEXT: [[LW64:%.*]] = mul i64 [[X]], [[Y]] @@ -1907,11 +1855,7 @@ define void @full_mul_int128__mul_use__y_hi(i64 %x, i64 %y, ptr %p) { ; CHECK-SAME: i64 [[X:%.*]], i64 [[Y:%.*]], ptr [[P:%.*]]) { ; CHECK-NEXT: [[Y_HI:%.*]] = lshr i64 [[Y]], 32 ; CHECK-NEXT: call void (...) @llvm.fake.use(i64 [[Y_HI]]) -; CHECK-NEXT: [[TMP1:%.*]] = zext i64 [[X]] to i128 -; CHECK-NEXT: [[TMP2:%.*]] = zext i64 [[Y]] to i128 -; CHECK-NEXT: [[TMP3:%.*]] = mul nuw i128 [[TMP1]], [[TMP2]] -; CHECK-NEXT: [[TMP4:%.*]] = lshr i128 [[TMP3]], 64 -; CHECK-NEXT: [[HW64:%.*]] = trunc nuw i128 [[TMP4]] to i64 +; CHECK-NEXT: [[HW64:%.*]] = call i64 @llvm.umulh.i64(i64 [[X]], i64 [[Y]]) ; CHECK-NEXT: [[HI_PTR:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 ; CHECK-NEXT: store i64 [[HW64]], ptr [[HI_PTR]], align 8 ; CHECK-NEXT: [[LW64:%.*]] = mul i64 [[X]], [[Y]] @@ -2188,11 +2132,7 @@ define void @full_mul_int128__mul_use__y_lo_x_lo(i64 %x, i64 %y, ptr %p) { ; CHECK-NEXT: [[Y_LO_X_LO:%.*]] = mul nuw i64 [[Y_LO]], [[X_LO]] ; CHECK-NEXT: call void (...) @llvm.fake.use(i64 [[Y_LO_X_LO]]) ; CHECK-NEXT: [[TMP6:%.*]] = add i64 [[UPPER_MID_WITH_CROSS]], [[LOW_ACCUM_HI]] -; CHECK-NEXT: [[TMP1:%.*]] = zext i64 [[X]] to i128 -; CHECK-NEXT: [[TMP2:%.*]] = zext i64 [[Y]] to i128 -; CHECK-NEXT: [[TMP3:%.*]] = mul nuw i128 [[TMP1]], [[TMP2]] -; CHECK-NEXT: [[TMP4:%.*]] = lshr i128 [[TMP3]], 64 -; CHECK-NEXT: [[TMP5:%.*]] = trunc nuw i128 [[TMP4]] to i64 +; CHECK-NEXT: [[TMP5:%.*]] = call i64 @llvm.umulh.i64(i64 [[X]], i64 [[Y]]) ; CHECK-NEXT: [[HI_PTR:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 ; CHECK-NEXT: store i64 [[TMP5]], ptr [[HI_PTR]], align 8 ; CHECK-NEXT: [[LOW_ACCUM1:%.*]] = shl i64 [[TMP6]], 32 @@ -2964,11 +2904,7 @@ define void @full_mul_int128__mul_use__upper_mid_with_cross(i64 %x, i64 %y, ptr define void @full_mul_int128__mul_use__low_accum_shifted(i64 %x, i64 %y, ptr %p) { ; CHECK-LABEL: define void @full_mul_int128__mul_use__low_accum_shifted( ; CHECK-SAME: i64 [[X:%.*]], i64 [[Y:%.*]], ptr [[P:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = zext i64 [[X]] to i128 -; CHECK-NEXT: [[TMP2:%.*]] = zext i64 [[Y]] to i128 -; CHECK-NEXT: [[TMP3:%.*]] = mul nuw i128 [[TMP1]], [[TMP2]] -; CHECK-NEXT: [[TMP4:%.*]] = lshr i128 [[TMP3]], 64 -; CHECK-NEXT: [[TMP5:%.*]] = trunc nuw i128 [[TMP4]] to i64 +; CHECK-NEXT: [[TMP5:%.*]] = call i64 @llvm.umulh.i64(i64 [[X]], i64 [[Y]]) ; CHECK-NEXT: [[HI_PTR:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 ; CHECK-NEXT: store i64 [[TMP5]], ptr [[HI_PTR]], align 8 ; CHECK-NEXT: [[LW64:%.*]] = mul i64 [[X]], [[Y]] diff --git a/llvm/test/Transforms/AggressiveInstCombine/umulh_ladder.ll b/llvm/test/Transforms/AggressiveInstCombine/umulh_ladder.ll index 257cc0315c72f..3c86fa45944dd 100644 --- a/llvm/test/Transforms/AggressiveInstCombine/umulh_ladder.ll +++ b/llvm/test/Transforms/AggressiveInstCombine/umulh_ladder.ll @@ -5,11 +5,7 @@ define i64 @umulh_variant(i64 %x, i64 %y) { ; CHECK-LABEL: define i64 @umulh_variant( ; CHECK-SAME: i64 [[X:%.*]], i64 [[Y:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = zext i64 [[Y]] to i128 -; CHECK-N... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/224311 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
