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

Reply via email to