[llvm] [InstCombine] Add generic smulh/umulh identity folds (PR #227335)
Simon Pilgrim via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 1 02:16:38 PDT 2026
https://github.com/RKSimon updated https://github.com/llvm/llvm-project/pull/227335
>From 086f241f8b98378043c5e3425bf1056ce1acf163 Mon Sep 17 00:00:00 2001
From: Simon Pilgrim <llvm-dev at redking.me.uk>
Date: Tue, 29 Sep 2026 15:11:07 +0100
Subject: [PATCH 1/7] [InstCombine] Add baseline smulh/umulh tests
Branched from equivalent x86 pmulh/pmulhu tests
---
llvm/test/Transforms/InstCombine/smulh.ll | 352 ++++++++++++++++++++++
llvm/test/Transforms/InstCombine/umulh.ll | 352 ++++++++++++++++++++++
2 files changed, 704 insertions(+)
create mode 100644 llvm/test/Transforms/InstCombine/smulh.ll
create mode 100644 llvm/test/Transforms/InstCombine/umulh.ll
diff --git a/llvm/test/Transforms/InstCombine/smulh.ll b/llvm/test/Transforms/InstCombine/smulh.ll
new file mode 100644
index 0000000000000..beb837627edf2
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/smulh.ll
@@ -0,0 +1,352 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -passes=instcombine -S | FileCheck %s
+
+;
+; UNDEF Elts
+;
+
+define i32 @undef_smulh_i32(i32 %a0) {
+; CHECK-LABEL: @undef_smulh_i32(
+; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.smulh.i32(i32 [[A0:%.*]], i32 undef)
+; CHECK-NEXT: ret i32 [[TMP1]]
+;
+ %1 = call i32 @llvm.smulh.i32(i32 %a0, i32 undef)
+ ret i32 %1
+}
+
+define i32 @undef_smulh_i32_commute(i32 %a0) {
+; CHECK-LABEL: @undef_smulh_i32_commute(
+; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.smulh.i32(i32 [[A0:%.*]], i32 undef)
+; CHECK-NEXT: ret i32 [[TMP1]]
+;
+ %1 = call i32 @llvm.smulh.i32(i32 undef, i32 %a0)
+ ret i32 %1
+}
+
+define <8 x i16> @undef_smulh_v8i16(<8 x i16> %a0) {
+; CHECK-LABEL: @undef_smulh_v8i16(
+; CHECK-NEXT: [[TMP1:%.*]] = call <8 x i16> @llvm.smulh.v8i16(<8 x i16> [[A0:%.*]], <8 x i16> undef)
+; CHECK-NEXT: ret <8 x i16> [[TMP1]]
+;
+ %1 = call <8 x i16> @llvm.smulh.v8i16(<8 x i16> %a0, <8 x i16> undef)
+ ret <8 x i16> %1
+}
+
+define <8 x i16> @undef_smulh_v8i16_commute(<8 x i16> %a0) {
+; CHECK-LABEL: @undef_smulh_v8i16_commute(
+; CHECK-NEXT: [[TMP1:%.*]] = call <8 x i16> @llvm.smulh.v8i16(<8 x i16> [[A0:%.*]], <8 x i16> undef)
+; CHECK-NEXT: ret <8 x i16> [[TMP1]]
+;
+ %1 = call <8 x i16> @llvm.smulh.v8i16(<8 x i16> undef, <8 x i16> %a0)
+ ret <8 x i16> %1
+}
+
+define <16 x i16> @undef_smulh_v16i16(<16 x i16> %a0) {
+; CHECK-LABEL: @undef_smulh_v16i16(
+; CHECK-NEXT: [[TMP1:%.*]] = call <16 x i16> @llvm.smulh.v16i16(<16 x i16> [[A0:%.*]], <16 x i16> undef)
+; CHECK-NEXT: ret <16 x i16> [[TMP1]]
+;
+ %1 = call <16 x i16> @llvm.smulh.v16i16(<16 x i16> %a0, <16 x i16> undef)
+ ret <16 x i16> %1
+}
+
+define <16 x i16> @undef_smulh_v16i16_commute(<16 x i16> %a0) {
+; CHECK-LABEL: @undef_smulh_v16i16_commute(
+; CHECK-NEXT: [[TMP1:%.*]] = call <16 x i16> @llvm.smulh.v16i16(<16 x i16> [[A0:%.*]], <16 x i16> undef)
+; CHECK-NEXT: ret <16 x i16> [[TMP1]]
+;
+ %1 = call <16 x i16> @llvm.smulh.v16i16(<16 x i16> undef, <16 x i16> %a0)
+ ret <16 x i16> %1
+}
+
+define <32 x i16> @undef_smulh_v32i16(<32 x i16> %a0) {
+; CHECK-LABEL: @undef_smulh_v32i16(
+; CHECK-NEXT: [[TMP1:%.*]] = call <32 x i16> @llvm.smulh.v32i16(<32 x i16> [[A0:%.*]], <32 x i16> undef)
+; CHECK-NEXT: ret <32 x i16> [[TMP1]]
+;
+ %1 = call <32 x i16> @llvm.smulh.v32i16(<32 x i16> %a0, <32 x i16> undef)
+ ret <32 x i16> %1
+}
+
+define <32 x i16> @undef_smulh_v32i16_commute(<32 x i16> %a0) {
+; CHECK-LABEL: @undef_smulh_v32i16_commute(
+; CHECK-NEXT: [[TMP1:%.*]] = call <32 x i16> @llvm.smulh.v32i16(<32 x i16> [[A0:%.*]], <32 x i16> undef)
+; CHECK-NEXT: ret <32 x i16> [[TMP1]]
+;
+ %1 = call <32 x i16> @llvm.smulh.v32i16(<32 x i16> undef, <32 x i16> %a0)
+ ret <32 x i16> %1
+}
+
+;
+; Zero Elts
+;
+
+define i32 @zero_smulh_i32(i32 %a0) {
+; CHECK-LABEL: @zero_smulh_i32(
+; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.smulh.i32(i32 [[A0:%.*]], i32 0)
+; CHECK-NEXT: ret i32 [[TMP1]]
+;
+ %1 = call i32 @llvm.smulh.i32(i32 %a0, i32 zeroinitializer)
+ ret i32 %1
+}
+
+define i32 @zero_smulh_i32_commute(i32 %a0) {
+; CHECK-LABEL: @zero_smulh_i32_commute(
+; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.smulh.i32(i32 [[A0:%.*]], i32 0)
+; CHECK-NEXT: ret i32 [[TMP1]]
+;
+ %1 = call i32 @llvm.smulh.i32(i32 zeroinitializer, i32 %a0)
+ ret i32 %1
+}
+
+define <8 x i16> @zero_smulh_v8i16(<8 x i16> %a0) {
+; CHECK-LABEL: @zero_smulh_v8i16(
+; CHECK-NEXT: [[TMP1:%.*]] = call <8 x i16> @llvm.smulh.v8i16(<8 x i16> [[A0:%.*]], <8 x i16> zeroinitializer)
+; CHECK-NEXT: ret <8 x i16> [[TMP1]]
+;
+ %1 = call <8 x i16> @llvm.smulh.v8i16(<8 x i16> %a0, <8 x i16> zeroinitializer)
+ ret <8 x i16> %1
+}
+
+define <8 x i16> @zero_smulh_v8i16_commute(<8 x i16> %a0) {
+; CHECK-LABEL: @zero_smulh_v8i16_commute(
+; CHECK-NEXT: [[TMP1:%.*]] = call <8 x i16> @llvm.smulh.v8i16(<8 x i16> [[A0:%.*]], <8 x i16> zeroinitializer)
+; CHECK-NEXT: ret <8 x i16> [[TMP1]]
+;
+ %1 = call <8 x i16> @llvm.smulh.v8i16(<8 x i16> zeroinitializer, <8 x i16> %a0)
+ ret <8 x i16> %1
+}
+
+define <16 x i16> @zero_smulh_v16i16(<16 x i16> %a0) {
+; CHECK-LABEL: @zero_smulh_v16i16(
+; CHECK-NEXT: [[TMP1:%.*]] = call <16 x i16> @llvm.smulh.v16i16(<16 x i16> [[A0:%.*]], <16 x i16> zeroinitializer)
+; CHECK-NEXT: ret <16 x i16> [[TMP1]]
+;
+ %1 = call <16 x i16> @llvm.smulh.v16i16(<16 x i16> %a0, <16 x i16> zeroinitializer)
+ ret <16 x i16> %1
+}
+
+define <16 x i16> @zero_smulh_v16i16_commute(<16 x i16> %a0) {
+; CHECK-LABEL: @zero_smulh_v16i16_commute(
+; CHECK-NEXT: [[TMP1:%.*]] = call <16 x i16> @llvm.smulh.v16i16(<16 x i16> [[A0:%.*]], <16 x i16> zeroinitializer)
+; CHECK-NEXT: ret <16 x i16> [[TMP1]]
+;
+ %1 = call <16 x i16> @llvm.smulh.v16i16(<16 x i16> zeroinitializer, <16 x i16> %a0)
+ ret <16 x i16> %1
+}
+
+define <32 x i16> @zero_smulh_v32i16(<32 x i16> %a0) {
+; CHECK-LABEL: @zero_smulh_v32i16(
+; CHECK-NEXT: [[TMP1:%.*]] = call <32 x i16> @llvm.smulh.v32i16(<32 x i16> [[A0:%.*]], <32 x i16> zeroinitializer)
+; CHECK-NEXT: ret <32 x i16> [[TMP1]]
+;
+ %1 = call <32 x i16> @llvm.smulh.v32i16(<32 x i16> %a0, <32 x i16> zeroinitializer)
+ ret <32 x i16> %1
+}
+
+define <32 x i16> @zero_smulh_v32i16_commute(<32 x i16> %a0) {
+; CHECK-LABEL: @zero_smulh_v32i16_commute(
+; CHECK-NEXT: [[TMP1:%.*]] = call <32 x i16> @llvm.smulh.v32i16(<32 x i16> [[A0:%.*]], <32 x i16> zeroinitializer)
+; CHECK-NEXT: ret <32 x i16> [[TMP1]]
+;
+ %1 = call <32 x i16> @llvm.smulh.v32i16(<32 x i16> zeroinitializer, <32 x i16> %a0)
+ ret <32 x i16> %1
+}
+
+;
+; Multiply by One
+;
+
+define i32 @one_smulh_i32(i32 %a0) {
+; CHECK-LABEL: @one_smulh_i32(
+; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.smulh.i32(i32 [[A0:%.*]], i32 1)
+; CHECK-NEXT: ret i32 [[TMP1]]
+;
+ %1 = call i32 @llvm.smulh.i32(i32 %a0, i32 1)
+ ret i32 %1
+}
+
+define i32 @one_smulh_i32_commute(i32 %a0) {
+; CHECK-LABEL: @one_smulh_i32_commute(
+; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.smulh.i32(i32 [[A0:%.*]], i32 1)
+; CHECK-NEXT: ret i32 [[TMP1]]
+;
+ %1 = call i32 @llvm.smulh.i32(i32 1, i32 %a0)
+ ret i32 %1
+}
+
+define <8 x i16> @one_smulh_v8i16(<8 x i16> %a0) {
+; CHECK-LABEL: @one_smulh_v8i16(
+; CHECK-NEXT: [[TMP1:%.*]] = call <8 x i16> @llvm.smulh.v8i16(<8 x i16> [[A0:%.*]], <8 x i16> splat (i16 1))
+; CHECK-NEXT: ret <8 x i16> [[TMP1]]
+;
+ %1 = call <8 x i16> @llvm.smulh.v8i16(<8 x i16> %a0, <8 x i16> <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>)
+ ret <8 x i16> %1
+}
+
+define <8 x i16> @one_smulh_v8i16_commute(<8 x i16> %a0) {
+; CHECK-LABEL: @one_smulh_v8i16_commute(
+; CHECK-NEXT: [[TMP1:%.*]] = call <8 x i16> @llvm.smulh.v8i16(<8 x i16> [[A0:%.*]], <8 x i16> splat (i16 1))
+; CHECK-NEXT: ret <8 x i16> [[TMP1]]
+;
+ %1 = call <8 x i16> @llvm.smulh.v8i16(<8 x i16> <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>, <8 x i16> %a0)
+ ret <8 x i16> %1
+}
+
+define <16 x i16> @one_smulh_v16i16(<16 x i16> %a0) {
+; CHECK-LABEL: @one_smulh_v16i16(
+; CHECK-NEXT: [[TMP1:%.*]] = call <16 x i16> @llvm.smulh.v16i16(<16 x i16> [[A0:%.*]], <16 x i16> splat (i16 1))
+; CHECK-NEXT: ret <16 x i16> [[TMP1]]
+;
+ %1 = call <16 x i16> @llvm.smulh.v16i16(<16 x i16> %a0, <16 x i16> <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>)
+ ret <16 x i16> %1
+}
+
+define <16 x i16> @one_smulh_v16i16_commute(<16 x i16> %a0) {
+; CHECK-LABEL: @one_smulh_v16i16_commute(
+; CHECK-NEXT: [[TMP1:%.*]] = call <16 x i16> @llvm.smulh.v16i16(<16 x i16> [[A0:%.*]], <16 x i16> splat (i16 1))
+; CHECK-NEXT: ret <16 x i16> [[TMP1]]
+;
+ %1 = call <16 x i16> @llvm.smulh.v16i16(<16 x i16> <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>, <16 x i16> %a0)
+ ret <16 x i16> %1
+}
+
+define <32 x i16> @one_smulh_v32i16(<32 x i16> %a0) {
+; CHECK-LABEL: @one_smulh_v32i16(
+; CHECK-NEXT: [[TMP1:%.*]] = call <32 x i16> @llvm.smulh.v32i16(<32 x i16> [[A0:%.*]], <32 x i16> splat (i16 1))
+; CHECK-NEXT: ret <32 x i16> [[TMP1]]
+;
+ %1 = call <32 x i16> @llvm.smulh.v32i16(<32 x i16> %a0, <32 x i16> <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>)
+ ret <32 x i16> %1
+}
+
+define <32 x i16> @one_smulh_v32i16_commute(<32 x i16> %a0) {
+; CHECK-LABEL: @one_smulh_v32i16_commute(
+; CHECK-NEXT: [[TMP1:%.*]] = call <32 x i16> @llvm.smulh.v32i16(<32 x i16> [[A0:%.*]], <32 x i16> splat (i16 1))
+; CHECK-NEXT: ret <32 x i16> [[TMP1]]
+;
+ %1 = call <32 x i16> @llvm.smulh.v32i16(<32 x i16> <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>, <32 x i16> %a0)
+ ret <32 x i16> %1
+}
+
+;
+; Constant Folding
+;
+
+define i32 @fold_smulh_i32() {
+; CHECK-LABEL: @fold_smulh_i32(
+; CHECK-NEXT: ret i32 -1
+;
+ %1 = call i32 @llvm.smulh.v8i16(i32 2, i32 -32768)
+ ret i32 %1
+}
+
+define <8 x i16> @fold_smulh_v8i16() {
+; CHECK-LABEL: @fold_smulh_v8i16(
+; CHECK-NEXT: ret <8 x i16> <i16 0, i16 0, i16 -2, i16 -2, i16 0, i16 -1, i16 -4, i16 -4>
+;
+ %1 = call <8 x i16> @llvm.smulh.v8i16(<8 x i16> <i16 -1, i16 2, i16 3, i16 -4, i16 -5, i16 6, i16 7, i16 -8>, <8 x i16> <i16 -5, i16 7, i16 -32768, i16 32765, i16 -9, i16 -11, i16 -32763, i16 32761>)
+ ret <8 x i16> %1
+}
+
+define <16 x i16> @fold_smulh_v16i16() {
+; CHECK-LABEL: @fold_smulh_v16i16(
+; CHECK-NEXT: ret <16 x i16> <i16 0, i16 -1, i16 -1, i16 1, i16 0, i16 0, i16 -3, i16 3, i16 -1, i16 -1, i16 4, i16 5, i16 -1, i16 -1, i16 6, i16 -8>
+;
+ %1 = call <16 x i16> @llvm.smulh.v16i16(<16 x i16> <i16 0, i16 -1, i16 2, i16 3, i16 -4, i16 -5, i16 6, i16 7, i16 -8, i16 9, i16 -10, i16 11, i16 -12, i16 13, i16 -14, i16 -15>, <16 x i16> <i16 -5, i16 7, i16 -32768, i16 32766, i16 -9, i16 -11, i16 -32764, i16 32762, i16 13, i16 -15, i16 -32760, i16 32758, i16 17, i16 -19, i16 -32756, i16 32756>)
+ ret <16 x i16> %1
+}
+
+define <32 x i16> @fold_smulh_v32i16() {
+; CHECK-LABEL: @fold_smulh_v32i16(
+; CHECK-NEXT: ret <32 x i16> <i16 0, i16 -1, i16 -1, i16 1, i16 0, i16 0, i16 -3, i16 3, i16 -1, i16 -1, i16 4, i16 5, i16 -1, i16 -1, i16 6, i16 -8, i16 0, i16 -1, i16 -1, i16 1, i16 0, i16 0, i16 -3, i16 3, i16 -1, i16 -1, i16 4, i16 5, i16 -1, i16 -1, i16 6, i16 -8>
+;
+ %1 = call <32 x i16> @llvm.smulh.v32i16(<32 x i16> <i16 0, i16 -1, i16 2, i16 3, i16 -4, i16 -5, i16 6, i16 7, i16 -8, i16 9, i16 -10, i16 11, i16 -12, i16 13, i16 -14, i16 -15, i16 -5, i16 7, i16 -32768, i16 32766, i16 -9, i16 -11, i16 -32764, i16 32762, i16 13, i16 -15, i16 -32760, i16 32758, i16 17, i16 -19, i16 -32756, i16 32756>, <32 x i16> <i16 -5, i16 7, i16 -32768, i16 32766, i16 -9, i16 -11, i16 -32764, i16 32762, i16 13, i16 -15, i16 -32760, i16 32758, i16 17, i16 -19, i16 -32756, i16 32756, i16 0, i16 -1, i16 2, i16 3, i16 -4, i16 -5, i16 6, i16 7, i16 -8, i16 9, i16 -10, i16 11, i16 -12, i16 13, i16 -14, i16 -15>)
+ ret <32 x i16> %1
+}
+
+;
+; Demanded Elts
+;
+
+define <8 x i16> @elts_smulh_v8i16(<8 x i16> %a0, <8 x i16> %a1) {
+; CHECK-LABEL: @elts_smulh_v8i16(
+; CHECK-NEXT: [[A0:%.*]] = shufflevector <8 x i16> [[A2:%.*]], <8 x i16> poison, <8 x i32> <i32 0, i32 1, i32 7, i32 6, i32 5, i32 4, i32 3, i32 2>
+; CHECK-NEXT: [[A1:%.*]] = shufflevector <8 x i16> [[A3:%.*]], <8 x i16> poison, <8 x i32> <i32 0, i32 1, i32 3, i32 2, i32 5, i32 4, i32 7, i32 6>
+; CHECK-NEXT: [[TMP1:%.*]] = call <8 x i16> @llvm.smulh.v8i16(<8 x i16> [[A0]], <8 x i16> [[A1]])
+; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <8 x i16> [[TMP1]], <8 x i16> poison, <8 x i32> zeroinitializer
+; CHECK-NEXT: ret <8 x i16> [[TMP2]]
+;
+ %1 = shufflevector <8 x i16> %a0, <8 x i16> undef, <8 x i32> <i32 0, i32 1, i32 7, i32 6, i32 5, i32 4, i32 3, i32 2>
+ %2 = shufflevector <8 x i16> %a1, <8 x i16> undef, <8 x i32> <i32 0, i32 1, i32 3, i32 2, i32 5, i32 4, i32 7, i32 6>
+ %3 = call <8 x i16> @llvm.smulh.v8i16(<8 x i16> %1, <8 x i16> %2)
+ %4 = shufflevector <8 x i16> %3, <8 x i16> poison, <8 x i32> zeroinitializer
+ ret <8 x i16> %4
+}
+
+define <16 x i16> @elts_smulh_v16i16(<16 x i16> %a0, <16 x i16> %a1) {
+; CHECK-LABEL: @elts_smulh_v16i16(
+; CHECK-NEXT: [[A0:%.*]] = shufflevector <16 x i16> [[A2:%.*]], <16 x i16> poison, <16 x i32> <i32 0, i32 1, i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
+; CHECK-NEXT: [[A1:%.*]] = shufflevector <16 x i16> [[A3:%.*]], <16 x i16> poison, <16 x i32> <i32 0, i32 1, i32 3, i32 2, i32 5, i32 4, i32 7, i32 6, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
+; CHECK-NEXT: [[TMP1:%.*]] = call <16 x i16> @llvm.smulh.v16i16(<16 x i16> [[A0]], <16 x i16> [[A1]])
+; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <16 x i16> [[TMP1]], <16 x i16> poison, <16 x i32> zeroinitializer
+; CHECK-NEXT: ret <16 x i16> [[TMP2]]
+;
+ %1 = shufflevector <16 x i16> %a0, <16 x i16> undef, <16 x i32> <i32 0, i32 1, i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
+ %2 = shufflevector <16 x i16> %a1, <16 x i16> undef, <16 x i32> <i32 0, i32 1, i32 3, i32 2, i32 5, i32 4, i32 7, i32 6, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
+ %3 = call <16 x i16> @llvm.smulh.v16i16(<16 x i16> %1, <16 x i16> %2)
+ %4 = shufflevector <16 x i16> %3, <16 x i16> poison, <16 x i32> zeroinitializer
+ ret <16 x i16> %4
+}
+
+define <32 x i16> @elts_smulh_v32i16(<32 x i16> %a0, <32 x i16> %a1) {
+; CHECK-LABEL: @elts_smulh_v32i16(
+; CHECK-NEXT: [[A0:%.*]] = shufflevector <32 x i16> [[A2:%.*]], <32 x i16> poison, <32 x i32> <i32 0, i32 1, i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>
+; CHECK-NEXT: [[A1:%.*]] = shufflevector <32 x i16> [[A3:%.*]], <32 x i16> poison, <32 x i32> <i32 0, i32 1, i32 3, i32 2, i32 5, i32 4, i32 7, i32 6, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>
+; CHECK-NEXT: [[TMP1:%.*]] = call <32 x i16> @llvm.smulh.v32i16(<32 x i16> [[A0]], <32 x i16> [[A1]])
+; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <32 x i16> [[TMP1]], <32 x i16> poison, <32 x i32> zeroinitializer
+; CHECK-NEXT: ret <32 x i16> [[TMP2]]
+;
+ %1 = shufflevector <32 x i16> %a0, <32 x i16> undef, <32 x i32> <i32 0, i32 1, i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>
+ %2 = shufflevector <32 x i16> %a1, <32 x i16> undef, <32 x i32> <i32 0, i32 1, i32 3, i32 2, i32 5, i32 4, i32 7, i32 6, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>
+ %3 = call <32 x i16> @llvm.smulh.v32i16(<32 x i16> %1, <32 x i16> %2)
+ %4 = shufflevector <32 x i16> %3, <32 x i16> poison, <32 x i32> zeroinitializer
+ ret <32 x i16> %4
+}
+
+;
+; Known Bits
+;
+
+define <8 x i16> @known_smulh_v8i16(<8 x i16> %a0, <8 x i16> %a1, <8 x i16> %a2) {
+; CHECK-LABEL: @known_smulh_v8i16(
+; CHECK-NEXT: ret <8 x i16> [[A2:%.*]]
+;
+ %x0 = lshr <8 x i16> %a0, <i16 8, i16 9, i16 10, i16 11, i16 12, i16 13, i16 14, i16 15>
+ %x1 = and <8 x i16> %a1, <i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3>
+ %m = tail call <8 x i16> @llvm.smulh.v8i16(<8 x i16> %x0, <8 x i16> %x1)
+ %r = add <8 x i16> %m, %a2
+ ret <8 x i16> %r
+}
+
+define <16 x i16> @known_smulh_v16i16(<16 x i16> %a0, <16 x i16> %a1, <16 x i16> %a2) {
+; CHECK-LABEL: @known_smulh_v16i16(
+; CHECK-NEXT: ret <16 x i16> [[A2:%.*]]
+;
+ %x0 = lshr <16 x i16> %a0, <i16 8, i16 9, i16 10, i16 11, i16 12, i16 13, i16 14, i16 15, i16 8, i16 9, i16 10, i16 11, i16 12, i16 13, i16 14, i16 15>
+ %x1 = and <16 x i16> %a1, <i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3>
+ %m = tail call <16 x i16> @llvm.smulh.v16i16(<16 x i16> %x0, <16 x i16> %x1)
+ %r = add <16 x i16> %m, %a2
+ ret <16 x i16> %r
+}
+
+define <32 x i16> @known_smulh_v32i16(<32 x i16> %a0, <32 x i16> %a1, <32 x i16> %a2) {
+; CHECK-LABEL: @known_smulh_v32i16(
+; CHECK-NEXT: ret <32 x i16> [[A2:%.*]]
+;
+ %x0 = lshr <32 x i16> %a0, <i16 8, i16 9, i16 10, i16 11, i16 12, i16 13, i16 14, i16 15, i16 8, i16 9, i16 10, i16 11, i16 12, i16 13, i16 14, i16 15, i16 8, i16 9, i16 10, i16 11, i16 12, i16 13, i16 14, i16 15, i16 8, i16 9, i16 10, i16 11, i16 12, i16 13, i16 14, i16 15>
+ %x1 = and <32 x i16> %a1, <i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3>
+ %m = tail call <32 x i16> @llvm.smulh.v32i16(<32 x i16> %x0, <32 x i16> %x1)
+ %r = add <32 x i16> %m, %a2
+ ret <32 x i16> %r
+}
diff --git a/llvm/test/Transforms/InstCombine/umulh.ll b/llvm/test/Transforms/InstCombine/umulh.ll
new file mode 100644
index 0000000000000..ccc21e603d69a
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/umulh.ll
@@ -0,0 +1,352 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -passes=instcombine -S | FileCheck %s
+
+;
+; UNDEF Elts
+;
+
+define i32 @undef_umulh_i32(i32 %a0) {
+; CHECK-LABEL: @undef_umulh_i32(
+; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umulh.i32(i32 [[A0:%.*]], i32 undef)
+; CHECK-NEXT: ret i32 [[TMP1]]
+;
+ %1 = call i32 @llvm.umulh.i32(i32 %a0, i32 undef)
+ ret i32 %1
+}
+
+define i32 @undef_umulh_i32_commute(i32 %a0) {
+; CHECK-LABEL: @undef_umulh_i32_commute(
+; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umulh.i32(i32 [[A0:%.*]], i32 undef)
+; CHECK-NEXT: ret i32 [[TMP1]]
+;
+ %1 = call i32 @llvm.umulh.i32(i32 undef, i32 %a0)
+ ret i32 %1
+}
+
+define <8 x i16> @undef_umulh_v8i16(<8 x i16> %a0) {
+; CHECK-LABEL: @undef_umulh_v8i16(
+; CHECK-NEXT: [[TMP1:%.*]] = call <8 x i16> @llvm.umulh.v8i16(<8 x i16> [[A0:%.*]], <8 x i16> undef)
+; CHECK-NEXT: ret <8 x i16> [[TMP1]]
+;
+ %1 = call <8 x i16> @llvm.umulh.v8i16(<8 x i16> %a0, <8 x i16> undef)
+ ret <8 x i16> %1
+}
+
+define <8 x i16> @undef_umulh_v8i16_commute(<8 x i16> %a0) {
+; CHECK-LABEL: @undef_umulh_v8i16_commute(
+; CHECK-NEXT: [[TMP1:%.*]] = call <8 x i16> @llvm.umulh.v8i16(<8 x i16> [[A0:%.*]], <8 x i16> undef)
+; CHECK-NEXT: ret <8 x i16> [[TMP1]]
+;
+ %1 = call <8 x i16> @llvm.umulh.v8i16(<8 x i16> undef, <8 x i16> %a0)
+ ret <8 x i16> %1
+}
+
+define <16 x i16> @undef_umulh_v16i16(<16 x i16> %a0) {
+; CHECK-LABEL: @undef_umulh_v16i16(
+; CHECK-NEXT: [[TMP1:%.*]] = call <16 x i16> @llvm.umulh.v16i16(<16 x i16> [[A0:%.*]], <16 x i16> undef)
+; CHECK-NEXT: ret <16 x i16> [[TMP1]]
+;
+ %1 = call <16 x i16> @llvm.umulh.v16i16(<16 x i16> %a0, <16 x i16> undef)
+ ret <16 x i16> %1
+}
+
+define <16 x i16> @undef_umulh_v16i16_commute(<16 x i16> %a0) {
+; CHECK-LABEL: @undef_umulh_v16i16_commute(
+; CHECK-NEXT: [[TMP1:%.*]] = call <16 x i16> @llvm.umulh.v16i16(<16 x i16> [[A0:%.*]], <16 x i16> undef)
+; CHECK-NEXT: ret <16 x i16> [[TMP1]]
+;
+ %1 = call <16 x i16> @llvm.umulh.v16i16(<16 x i16> undef, <16 x i16> %a0)
+ ret <16 x i16> %1
+}
+
+define <32 x i16> @undef_umulh_v32i16(<32 x i16> %a0) {
+; CHECK-LABEL: @undef_umulh_v32i16(
+; CHECK-NEXT: [[TMP1:%.*]] = call <32 x i16> @llvm.umulh.v32i16(<32 x i16> [[A0:%.*]], <32 x i16> undef)
+; CHECK-NEXT: ret <32 x i16> [[TMP1]]
+;
+ %1 = call <32 x i16> @llvm.umulh.v32i16(<32 x i16> %a0, <32 x i16> undef)
+ ret <32 x i16> %1
+}
+
+define <32 x i16> @undef_umulh_v32i16_commute(<32 x i16> %a0) {
+; CHECK-LABEL: @undef_umulh_v32i16_commute(
+; CHECK-NEXT: [[TMP1:%.*]] = call <32 x i16> @llvm.umulh.v32i16(<32 x i16> [[A0:%.*]], <32 x i16> undef)
+; CHECK-NEXT: ret <32 x i16> [[TMP1]]
+;
+ %1 = call <32 x i16> @llvm.umulh.v32i16(<32 x i16> undef, <32 x i16> %a0)
+ ret <32 x i16> %1
+}
+
+;
+; Zero Elts
+;
+
+define i32 @zero_umulh_i32(i32 %a0) {
+; CHECK-LABEL: @zero_umulh_i32(
+; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umulh.i32(i32 [[A0:%.*]], i32 0)
+; CHECK-NEXT: ret i32 [[TMP1]]
+;
+ %1 = call i32 @llvm.umulh.i32(i32 %a0, i32 zeroinitializer)
+ ret i32 %1
+}
+
+define i32 @zero_umulh_i32_commute(i32 %a0) {
+; CHECK-LABEL: @zero_umulh_i32_commute(
+; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umulh.i32(i32 [[A0:%.*]], i32 0)
+; CHECK-NEXT: ret i32 [[TMP1]]
+;
+ %1 = call i32 @llvm.umulh.i32(i32 zeroinitializer, i32 %a0)
+ ret i32 %1
+}
+
+define <8 x i16> @zero_umulh_v8i16(<8 x i16> %a0) {
+; CHECK-LABEL: @zero_umulh_v8i16(
+; CHECK-NEXT: [[TMP1:%.*]] = call <8 x i16> @llvm.umulh.v8i16(<8 x i16> [[A0:%.*]], <8 x i16> zeroinitializer)
+; CHECK-NEXT: ret <8 x i16> [[TMP1]]
+;
+ %1 = call <8 x i16> @llvm.umulh.v8i16(<8 x i16> %a0, <8 x i16> zeroinitializer)
+ ret <8 x i16> %1
+}
+
+define <8 x i16> @zero_umulh_v8i16_commute(<8 x i16> %a0) {
+; CHECK-LABEL: @zero_umulh_v8i16_commute(
+; CHECK-NEXT: [[TMP1:%.*]] = call <8 x i16> @llvm.umulh.v8i16(<8 x i16> [[A0:%.*]], <8 x i16> zeroinitializer)
+; CHECK-NEXT: ret <8 x i16> [[TMP1]]
+;
+ %1 = call <8 x i16> @llvm.umulh.v8i16(<8 x i16> zeroinitializer, <8 x i16> %a0)
+ ret <8 x i16> %1
+}
+
+define <16 x i16> @zero_umulh_v16i16(<16 x i16> %a0) {
+; CHECK-LABEL: @zero_umulh_v16i16(
+; CHECK-NEXT: [[TMP1:%.*]] = call <16 x i16> @llvm.umulh.v16i16(<16 x i16> [[A0:%.*]], <16 x i16> zeroinitializer)
+; CHECK-NEXT: ret <16 x i16> [[TMP1]]
+;
+ %1 = call <16 x i16> @llvm.umulh.v16i16(<16 x i16> %a0, <16 x i16> zeroinitializer)
+ ret <16 x i16> %1
+}
+
+define <16 x i16> @zero_umulh_v16i16_commute(<16 x i16> %a0) {
+; CHECK-LABEL: @zero_umulh_v16i16_commute(
+; CHECK-NEXT: [[TMP1:%.*]] = call <16 x i16> @llvm.umulh.v16i16(<16 x i16> [[A0:%.*]], <16 x i16> zeroinitializer)
+; CHECK-NEXT: ret <16 x i16> [[TMP1]]
+;
+ %1 = call <16 x i16> @llvm.umulh.v16i16(<16 x i16> zeroinitializer, <16 x i16> %a0)
+ ret <16 x i16> %1
+}
+
+define <32 x i16> @zero_umulh_v32i16(<32 x i16> %a0) {
+; CHECK-LABEL: @zero_umulh_v32i16(
+; CHECK-NEXT: [[TMP1:%.*]] = call <32 x i16> @llvm.umulh.v32i16(<32 x i16> [[A0:%.*]], <32 x i16> zeroinitializer)
+; CHECK-NEXT: ret <32 x i16> [[TMP1]]
+;
+ %1 = call <32 x i16> @llvm.umulh.v32i16(<32 x i16> %a0, <32 x i16> zeroinitializer)
+ ret <32 x i16> %1
+}
+
+define <32 x i16> @zero_umulh_v32i16_commute(<32 x i16> %a0) {
+; CHECK-LABEL: @zero_umulh_v32i16_commute(
+; CHECK-NEXT: [[TMP1:%.*]] = call <32 x i16> @llvm.umulh.v32i16(<32 x i16> [[A0:%.*]], <32 x i16> zeroinitializer)
+; CHECK-NEXT: ret <32 x i16> [[TMP1]]
+;
+ %1 = call <32 x i16> @llvm.umulh.v32i16(<32 x i16> zeroinitializer, <32 x i16> %a0)
+ ret <32 x i16> %1
+}
+
+;
+; Multiply by One
+;
+
+define i32 @one_umulh_i32(i32 %a0) {
+; CHECK-LABEL: @one_umulh_i32(
+; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umulh.i32(i32 [[A0:%.*]], i32 1)
+; CHECK-NEXT: ret i32 [[TMP1]]
+;
+ %1 = call i32 @llvm.umulh.i32(i32 %a0, i32 1)
+ ret i32 %1
+}
+
+define i32 @one_umulh_i32_commute(i32 %a0) {
+; CHECK-LABEL: @one_umulh_i32_commute(
+; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umulh.i32(i32 [[A0:%.*]], i32 1)
+; CHECK-NEXT: ret i32 [[TMP1]]
+;
+ %1 = call i32 @llvm.umulh.i32(i32 1, i32 %a0)
+ ret i32 %1
+}
+
+define <8 x i16> @one_umulh_v8i16(<8 x i16> %a0) {
+; CHECK-LABEL: @one_umulh_v8i16(
+; CHECK-NEXT: [[TMP1:%.*]] = call <8 x i16> @llvm.umulh.v8i16(<8 x i16> [[A0:%.*]], <8 x i16> splat (i16 1))
+; CHECK-NEXT: ret <8 x i16> [[TMP1]]
+;
+ %1 = call <8 x i16> @llvm.umulh.v8i16(<8 x i16> %a0, <8 x i16> <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>)
+ ret <8 x i16> %1
+}
+
+define <8 x i16> @one_umulh_v8i16_commute(<8 x i16> %a0) {
+; CHECK-LABEL: @one_umulh_v8i16_commute(
+; CHECK-NEXT: [[TMP1:%.*]] = call <8 x i16> @llvm.umulh.v8i16(<8 x i16> [[A0:%.*]], <8 x i16> splat (i16 1))
+; CHECK-NEXT: ret <8 x i16> [[TMP1]]
+;
+ %1 = call <8 x i16> @llvm.umulh.v8i16(<8 x i16> <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>, <8 x i16> %a0)
+ ret <8 x i16> %1
+}
+
+define <16 x i16> @one_umulh_v16i16(<16 x i16> %a0) {
+; CHECK-LABEL: @one_umulh_v16i16(
+; CHECK-NEXT: [[TMP1:%.*]] = call <16 x i16> @llvm.umulh.v16i16(<16 x i16> [[A0:%.*]], <16 x i16> splat (i16 1))
+; CHECK-NEXT: ret <16 x i16> [[TMP1]]
+;
+ %1 = call <16 x i16> @llvm.umulh.v16i16(<16 x i16> %a0, <16 x i16> <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>)
+ ret <16 x i16> %1
+}
+
+define <16 x i16> @one_umulh_v16i16_commute(<16 x i16> %a0) {
+; CHECK-LABEL: @one_umulh_v16i16_commute(
+; CHECK-NEXT: [[TMP1:%.*]] = call <16 x i16> @llvm.umulh.v16i16(<16 x i16> [[A0:%.*]], <16 x i16> splat (i16 1))
+; CHECK-NEXT: ret <16 x i16> [[TMP1]]
+;
+ %1 = call <16 x i16> @llvm.umulh.v16i16(<16 x i16> <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>, <16 x i16> %a0)
+ ret <16 x i16> %1
+}
+
+define <32 x i16> @one_umulh_v32i16(<32 x i16> %a0) {
+; CHECK-LABEL: @one_umulh_v32i16(
+; CHECK-NEXT: [[TMP1:%.*]] = call <32 x i16> @llvm.umulh.v32i16(<32 x i16> [[A0:%.*]], <32 x i16> splat (i16 1))
+; CHECK-NEXT: ret <32 x i16> [[TMP1]]
+;
+ %1 = call <32 x i16> @llvm.umulh.v32i16(<32 x i16> %a0, <32 x i16> <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>)
+ ret <32 x i16> %1
+}
+
+define <32 x i16> @one_umulh_v32i16_commute(<32 x i16> %a0) {
+; CHECK-LABEL: @one_umulh_v32i16_commute(
+; CHECK-NEXT: [[TMP1:%.*]] = call <32 x i16> @llvm.umulh.v32i16(<32 x i16> [[A0:%.*]], <32 x i16> splat (i16 1))
+; CHECK-NEXT: ret <32 x i16> [[TMP1]]
+;
+ %1 = call <32 x i16> @llvm.umulh.v32i16(<32 x i16> <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>, <32 x i16> %a0)
+ ret <32 x i16> %1
+}
+
+;
+; Constant Folding
+;
+
+define i32 @fold_umulh_i32() {
+; CHECK-LABEL: @fold_umulh_i32(
+; CHECK-NEXT: ret i32 1
+;
+ %1 = call i32 @llvm.umulh.v8i16(i32 2, i32 -32768)
+ ret i32 %1
+}
+
+define <8 x i16> @fold_umulh_v8i16() {
+; CHECK-LABEL: @fold_umulh_v8i16(
+; CHECK-NEXT: ret <8 x i16> <i16 -6, i16 0, i16 1, i16 32763, i16 -14, i16 5, i16 3, i16 32757>
+;
+ %1 = call <8 x i16> @llvm.umulh.v8i16(<8 x i16> <i16 -1, i16 2, i16 3, i16 -4, i16 -5, i16 6, i16 7, i16 -8>, <8 x i16> <i16 -5, i16 7, i16 -32768, i16 32765, i16 -9, i16 -11, i16 -32763, i16 32761>)
+ ret <8 x i16> %1
+}
+
+define <16 x i16> @fold_umulh_v16i16() {
+; CHECK-LABEL: @fold_umulh_v16i16(
+; CHECK-NEXT: ret <16 x i16> <i16 0, i16 6, i16 1, i16 1, i16 -13, i16 -16, i16 3, i16 3, i16 12, i16 8, i16 -32766, i16 5, i16 16, i16 12, i16 -32764, i16 32748>
+;
+ %1 = call <16 x i16> @llvm.umulh.v16i16(<16 x i16> <i16 0, i16 -1, i16 2, i16 3, i16 -4, i16 -5, i16 6, i16 7, i16 -8, i16 9, i16 -10, i16 11, i16 -12, i16 13, i16 -14, i16 -15>, <16 x i16> <i16 -5, i16 7, i16 -32768, i16 32766, i16 -9, i16 -11, i16 -32764, i16 32762, i16 13, i16 -15, i16 -32760, i16 32758, i16 17, i16 -19, i16 -32756, i16 32756>)
+ ret <16 x i16> %1
+}
+
+define <32 x i16> @fold_umulh_v32i16() {
+; CHECK-LABEL: @fold_umulh_v32i16(
+; CHECK-NEXT: ret <32 x i16> <i16 0, i16 6, i16 1, i16 1, i16 -13, i16 -16, i16 3, i16 3, i16 12, i16 8, i16 -32766, i16 5, i16 16, i16 12, i16 -32764, i16 32748, i16 0, i16 6, i16 1, i16 1, i16 -13, i16 -16, i16 3, i16 3, i16 12, i16 8, i16 -32766, i16 5, i16 16, i16 12, i16 -32764, i16 32748>
+;
+ %1 = call <32 x i16> @llvm.umulh.v32i16(<32 x i16> <i16 0, i16 -1, i16 2, i16 3, i16 -4, i16 -5, i16 6, i16 7, i16 -8, i16 9, i16 -10, i16 11, i16 -12, i16 13, i16 -14, i16 -15, i16 -5, i16 7, i16 -32768, i16 32766, i16 -9, i16 -11, i16 -32764, i16 32762, i16 13, i16 -15, i16 -32760, i16 32758, i16 17, i16 -19, i16 -32756, i16 32756>, <32 x i16> <i16 -5, i16 7, i16 -32768, i16 32766, i16 -9, i16 -11, i16 -32764, i16 32762, i16 13, i16 -15, i16 -32760, i16 32758, i16 17, i16 -19, i16 -32756, i16 32756, i16 0, i16 -1, i16 2, i16 3, i16 -4, i16 -5, i16 6, i16 7, i16 -8, i16 9, i16 -10, i16 11, i16 -12, i16 13, i16 -14, i16 -15>)
+ ret <32 x i16> %1
+}
+
+;
+; Demanded Elts
+;
+
+define <8 x i16> @elts_umulh_v8i16(<8 x i16> %a0, <8 x i16> %a1) {
+; CHECK-LABEL: @elts_umulh_v8i16(
+; CHECK-NEXT: [[A0:%.*]] = shufflevector <8 x i16> [[A2:%.*]], <8 x i16> poison, <8 x i32> <i32 0, i32 1, i32 7, i32 6, i32 5, i32 4, i32 3, i32 2>
+; CHECK-NEXT: [[A1:%.*]] = shufflevector <8 x i16> [[A3:%.*]], <8 x i16> poison, <8 x i32> <i32 0, i32 1, i32 3, i32 2, i32 5, i32 4, i32 7, i32 6>
+; CHECK-NEXT: [[TMP1:%.*]] = call <8 x i16> @llvm.umulh.v8i16(<8 x i16> [[A0]], <8 x i16> [[A1]])
+; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <8 x i16> [[TMP1]], <8 x i16> poison, <8 x i32> zeroinitializer
+; CHECK-NEXT: ret <8 x i16> [[TMP2]]
+;
+ %1 = shufflevector <8 x i16> %a0, <8 x i16> undef, <8 x i32> <i32 0, i32 1, i32 7, i32 6, i32 5, i32 4, i32 3, i32 2>
+ %2 = shufflevector <8 x i16> %a1, <8 x i16> undef, <8 x i32> <i32 0, i32 1, i32 3, i32 2, i32 5, i32 4, i32 7, i32 6>
+ %3 = call <8 x i16> @llvm.umulh.v8i16(<8 x i16> %1, <8 x i16> %2)
+ %4 = shufflevector <8 x i16> %3, <8 x i16> poison, <8 x i32> zeroinitializer
+ ret <8 x i16> %4
+}
+
+define <16 x i16> @elts_umulh_v16i16(<16 x i16> %a0, <16 x i16> %a1) {
+; CHECK-LABEL: @elts_umulh_v16i16(
+; CHECK-NEXT: [[A0:%.*]] = shufflevector <16 x i16> [[A2:%.*]], <16 x i16> poison, <16 x i32> <i32 0, i32 1, i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
+; CHECK-NEXT: [[A1:%.*]] = shufflevector <16 x i16> [[A3:%.*]], <16 x i16> poison, <16 x i32> <i32 0, i32 1, i32 3, i32 2, i32 5, i32 4, i32 7, i32 6, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
+; CHECK-NEXT: [[TMP1:%.*]] = call <16 x i16> @llvm.umulh.v16i16(<16 x i16> [[A0]], <16 x i16> [[A1]])
+; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <16 x i16> [[TMP1]], <16 x i16> poison, <16 x i32> zeroinitializer
+; CHECK-NEXT: ret <16 x i16> [[TMP2]]
+;
+ %1 = shufflevector <16 x i16> %a0, <16 x i16> undef, <16 x i32> <i32 0, i32 1, i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
+ %2 = shufflevector <16 x i16> %a1, <16 x i16> undef, <16 x i32> <i32 0, i32 1, i32 3, i32 2, i32 5, i32 4, i32 7, i32 6, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
+ %3 = call <16 x i16> @llvm.umulh.v16i16(<16 x i16> %1, <16 x i16> %2)
+ %4 = shufflevector <16 x i16> %3, <16 x i16> poison, <16 x i32> zeroinitializer
+ ret <16 x i16> %4
+}
+
+define <32 x i16> @elts_umulh_v32i16(<32 x i16> %a0, <32 x i16> %a1) {
+; CHECK-LABEL: @elts_umulh_v32i16(
+; CHECK-NEXT: [[A0:%.*]] = shufflevector <32 x i16> [[A2:%.*]], <32 x i16> poison, <32 x i32> <i32 0, i32 1, i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>
+; CHECK-NEXT: [[A1:%.*]] = shufflevector <32 x i16> [[A3:%.*]], <32 x i16> poison, <32 x i32> <i32 0, i32 1, i32 3, i32 2, i32 5, i32 4, i32 7, i32 6, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>
+; CHECK-NEXT: [[TMP1:%.*]] = call <32 x i16> @llvm.umulh.v32i16(<32 x i16> [[A0]], <32 x i16> [[A1]])
+; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <32 x i16> [[TMP1]], <32 x i16> poison, <32 x i32> zeroinitializer
+; CHECK-NEXT: ret <32 x i16> [[TMP2]]
+;
+ %1 = shufflevector <32 x i16> %a0, <32 x i16> undef, <32 x i32> <i32 0, i32 1, i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>
+ %2 = shufflevector <32 x i16> %a1, <32 x i16> undef, <32 x i32> <i32 0, i32 1, i32 3, i32 2, i32 5, i32 4, i32 7, i32 6, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>
+ %3 = call <32 x i16> @llvm.umulh.v32i16(<32 x i16> %1, <32 x i16> %2)
+ %4 = shufflevector <32 x i16> %3, <32 x i16> poison, <32 x i32> zeroinitializer
+ ret <32 x i16> %4
+}
+
+;
+; Known Bits
+;
+
+define <8 x i16> @known_umulh_v8i16(<8 x i16> %a0, <8 x i16> %a1, <8 x i16> %a2) {
+; CHECK-LABEL: @known_umulh_v8i16(
+; CHECK-NEXT: ret <8 x i16> [[A2:%.*]]
+;
+ %x0 = lshr <8 x i16> %a0, <i16 8, i16 9, i16 10, i16 11, i16 12, i16 13, i16 14, i16 15>
+ %x1 = and <8 x i16> %a1, <i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3>
+ %m = tail call <8 x i16> @llvm.umulh.v8i16(<8 x i16> %x0, <8 x i16> %x1)
+ %r = add <8 x i16> %m, %a2
+ ret <8 x i16> %r
+}
+
+define <16 x i16> @known_umulh_v16i16(<16 x i16> %a0, <16 x i16> %a1, <16 x i16> %a2) {
+; CHECK-LABEL: @known_umulh_v16i16(
+; CHECK-NEXT: ret <16 x i16> [[A2:%.*]]
+;
+ %x0 = lshr <16 x i16> %a0, <i16 8, i16 9, i16 10, i16 11, i16 12, i16 13, i16 14, i16 15, i16 8, i16 9, i16 10, i16 11, i16 12, i16 13, i16 14, i16 15>
+ %x1 = and <16 x i16> %a1, <i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3>
+ %m = tail call <16 x i16> @llvm.umulh.v16i16(<16 x i16> %x0, <16 x i16> %x1)
+ %r = add <16 x i16> %m, %a2
+ ret <16 x i16> %r
+}
+
+define <32 x i16> @known_umulh_v32i16(<32 x i16> %a0, <32 x i16> %a1, <32 x i16> %a2) {
+; CHECK-LABEL: @known_umulh_v32i16(
+; CHECK-NEXT: ret <32 x i16> [[A2:%.*]]
+;
+ %x0 = lshr <32 x i16> %a0, <i16 8, i16 9, i16 10, i16 11, i16 12, i16 13, i16 14, i16 15, i16 8, i16 9, i16 10, i16 11, i16 12, i16 13, i16 14, i16 15, i16 8, i16 9, i16 10, i16 11, i16 12, i16 13, i16 14, i16 15, i16 8, i16 9, i16 10, i16 11, i16 12, i16 13, i16 14, i16 15>
+ %x1 = and <32 x i16> %a1, <i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3>
+ %m = tail call <32 x i16> @llvm.umulh.v32i16(<32 x i16> %x0, <32 x i16> %x1)
+ %r = add <32 x i16> %m, %a2
+ ret <32 x i16> %r
+}
>From f95ce4e9f42dd24ad38366a2d621f967ec09f518 Mon Sep 17 00:00:00 2001
From: Simon Pilgrim <llvm-dev at redking.me.uk>
Date: Tue, 29 Sep 2026 15:36:34 +0100
Subject: [PATCH 2/7] [InstCombine] Add generic smulh/umulh identity folds
[su]mulh(x,undef) -> 0
[su]mulh(x,0) -> 0
umulh(x,1) -> 0
smulh(x,1) -> sra(x,bw-1) // signsplat
Matches the x86 pmulh folds
---
.../InstCombine/InstCombineCalls.cpp | 29 ++++++++
llvm/test/Transforms/InstCombine/smulh.ll | 64 +++++++----------
llvm/test/Transforms/InstCombine/umulh.ll | 72 +++++++------------
3 files changed, 77 insertions(+), 88 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index efba8a57b49a0..8757dc169583d 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -2882,6 +2882,35 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
return &CI;
break;
}
+
+ case Intrinsic::smulh:
+ case Intrinsic::umulh: {
+ Value *Arg0 = II->getArgOperand(0);
+ Value *Arg1 = II->getArgOperand(1);
+ bool IsSigned = IID == Intrinsic::smulh;
+ unsigned BitWidth = II->getType()->getScalarSizeInBits();
+
+ // Multiply by undef -> zero (NOT undef!) as other arg could still be
+ // zero.
+ if (isa<UndefValue>(Arg0) || isa<UndefValue>(Arg1))
+ return replaceInstUsesWith(CI, ConstantInt::getNullValue(II->getType()));
+
+ // Multiply by zero.
+ if (match(Arg0, m_Zero()) || match(Arg1, m_Zero()))
+ return replaceInstUsesWith(CI, ConstantInt::getNullValue(II->getType()));
+
+ // Multiply by one.
+ if (match(Arg0, m_One()))
+ return replaceInstUsesWith(
+ CI, IsSigned ? Builder.CreateAShr(Arg1, BitWidth - 1)
+ : ConstantInt::getNullValue(II->getType()));
+ if (match(Arg1, m_One()))
+ return replaceInstUsesWith(
+ CI, IsSigned ? Builder.CreateAShr(Arg0, BitWidth - 1)
+ : ConstantInt::getNullValue(II->getType()));
+ break;
+ }
+
case Intrinsic::uadd_with_overflow:
case Intrinsic::sadd_with_overflow: {
if (Instruction *I = foldIntrinsicWithOverflowCommon(II))
diff --git a/llvm/test/Transforms/InstCombine/smulh.ll b/llvm/test/Transforms/InstCombine/smulh.ll
index beb837627edf2..f1e7632942afd 100644
--- a/llvm/test/Transforms/InstCombine/smulh.ll
+++ b/llvm/test/Transforms/InstCombine/smulh.ll
@@ -7,8 +7,7 @@
define i32 @undef_smulh_i32(i32 %a0) {
; CHECK-LABEL: @undef_smulh_i32(
-; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.smulh.i32(i32 [[A0:%.*]], i32 undef)
-; CHECK-NEXT: ret i32 [[TMP1]]
+; CHECK-NEXT: ret i32 0
;
%1 = call i32 @llvm.smulh.i32(i32 %a0, i32 undef)
ret i32 %1
@@ -16,8 +15,7 @@ define i32 @undef_smulh_i32(i32 %a0) {
define i32 @undef_smulh_i32_commute(i32 %a0) {
; CHECK-LABEL: @undef_smulh_i32_commute(
-; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.smulh.i32(i32 [[A0:%.*]], i32 undef)
-; CHECK-NEXT: ret i32 [[TMP1]]
+; CHECK-NEXT: ret i32 0
;
%1 = call i32 @llvm.smulh.i32(i32 undef, i32 %a0)
ret i32 %1
@@ -25,8 +23,7 @@ define i32 @undef_smulh_i32_commute(i32 %a0) {
define <8 x i16> @undef_smulh_v8i16(<8 x i16> %a0) {
; CHECK-LABEL: @undef_smulh_v8i16(
-; CHECK-NEXT: [[TMP1:%.*]] = call <8 x i16> @llvm.smulh.v8i16(<8 x i16> [[A0:%.*]], <8 x i16> undef)
-; CHECK-NEXT: ret <8 x i16> [[TMP1]]
+; CHECK-NEXT: ret <8 x i16> zeroinitializer
;
%1 = call <8 x i16> @llvm.smulh.v8i16(<8 x i16> %a0, <8 x i16> undef)
ret <8 x i16> %1
@@ -34,8 +31,7 @@ define <8 x i16> @undef_smulh_v8i16(<8 x i16> %a0) {
define <8 x i16> @undef_smulh_v8i16_commute(<8 x i16> %a0) {
; CHECK-LABEL: @undef_smulh_v8i16_commute(
-; CHECK-NEXT: [[TMP1:%.*]] = call <8 x i16> @llvm.smulh.v8i16(<8 x i16> [[A0:%.*]], <8 x i16> undef)
-; CHECK-NEXT: ret <8 x i16> [[TMP1]]
+; CHECK-NEXT: ret <8 x i16> zeroinitializer
;
%1 = call <8 x i16> @llvm.smulh.v8i16(<8 x i16> undef, <8 x i16> %a0)
ret <8 x i16> %1
@@ -43,8 +39,7 @@ define <8 x i16> @undef_smulh_v8i16_commute(<8 x i16> %a0) {
define <16 x i16> @undef_smulh_v16i16(<16 x i16> %a0) {
; CHECK-LABEL: @undef_smulh_v16i16(
-; CHECK-NEXT: [[TMP1:%.*]] = call <16 x i16> @llvm.smulh.v16i16(<16 x i16> [[A0:%.*]], <16 x i16> undef)
-; CHECK-NEXT: ret <16 x i16> [[TMP1]]
+; CHECK-NEXT: ret <16 x i16> zeroinitializer
;
%1 = call <16 x i16> @llvm.smulh.v16i16(<16 x i16> %a0, <16 x i16> undef)
ret <16 x i16> %1
@@ -52,8 +47,7 @@ define <16 x i16> @undef_smulh_v16i16(<16 x i16> %a0) {
define <16 x i16> @undef_smulh_v16i16_commute(<16 x i16> %a0) {
; CHECK-LABEL: @undef_smulh_v16i16_commute(
-; CHECK-NEXT: [[TMP1:%.*]] = call <16 x i16> @llvm.smulh.v16i16(<16 x i16> [[A0:%.*]], <16 x i16> undef)
-; CHECK-NEXT: ret <16 x i16> [[TMP1]]
+; CHECK-NEXT: ret <16 x i16> zeroinitializer
;
%1 = call <16 x i16> @llvm.smulh.v16i16(<16 x i16> undef, <16 x i16> %a0)
ret <16 x i16> %1
@@ -61,8 +55,7 @@ define <16 x i16> @undef_smulh_v16i16_commute(<16 x i16> %a0) {
define <32 x i16> @undef_smulh_v32i16(<32 x i16> %a0) {
; CHECK-LABEL: @undef_smulh_v32i16(
-; CHECK-NEXT: [[TMP1:%.*]] = call <32 x i16> @llvm.smulh.v32i16(<32 x i16> [[A0:%.*]], <32 x i16> undef)
-; CHECK-NEXT: ret <32 x i16> [[TMP1]]
+; CHECK-NEXT: ret <32 x i16> zeroinitializer
;
%1 = call <32 x i16> @llvm.smulh.v32i16(<32 x i16> %a0, <32 x i16> undef)
ret <32 x i16> %1
@@ -70,8 +63,7 @@ define <32 x i16> @undef_smulh_v32i16(<32 x i16> %a0) {
define <32 x i16> @undef_smulh_v32i16_commute(<32 x i16> %a0) {
; CHECK-LABEL: @undef_smulh_v32i16_commute(
-; CHECK-NEXT: [[TMP1:%.*]] = call <32 x i16> @llvm.smulh.v32i16(<32 x i16> [[A0:%.*]], <32 x i16> undef)
-; CHECK-NEXT: ret <32 x i16> [[TMP1]]
+; CHECK-NEXT: ret <32 x i16> zeroinitializer
;
%1 = call <32 x i16> @llvm.smulh.v32i16(<32 x i16> undef, <32 x i16> %a0)
ret <32 x i16> %1
@@ -83,8 +75,7 @@ define <32 x i16> @undef_smulh_v32i16_commute(<32 x i16> %a0) {
define i32 @zero_smulh_i32(i32 %a0) {
; CHECK-LABEL: @zero_smulh_i32(
-; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.smulh.i32(i32 [[A0:%.*]], i32 0)
-; CHECK-NEXT: ret i32 [[TMP1]]
+; CHECK-NEXT: ret i32 0
;
%1 = call i32 @llvm.smulh.i32(i32 %a0, i32 zeroinitializer)
ret i32 %1
@@ -92,8 +83,7 @@ define i32 @zero_smulh_i32(i32 %a0) {
define i32 @zero_smulh_i32_commute(i32 %a0) {
; CHECK-LABEL: @zero_smulh_i32_commute(
-; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.smulh.i32(i32 [[A0:%.*]], i32 0)
-; CHECK-NEXT: ret i32 [[TMP1]]
+; CHECK-NEXT: ret i32 0
;
%1 = call i32 @llvm.smulh.i32(i32 zeroinitializer, i32 %a0)
ret i32 %1
@@ -101,8 +91,7 @@ define i32 @zero_smulh_i32_commute(i32 %a0) {
define <8 x i16> @zero_smulh_v8i16(<8 x i16> %a0) {
; CHECK-LABEL: @zero_smulh_v8i16(
-; CHECK-NEXT: [[TMP1:%.*]] = call <8 x i16> @llvm.smulh.v8i16(<8 x i16> [[A0:%.*]], <8 x i16> zeroinitializer)
-; CHECK-NEXT: ret <8 x i16> [[TMP1]]
+; CHECK-NEXT: ret <8 x i16> zeroinitializer
;
%1 = call <8 x i16> @llvm.smulh.v8i16(<8 x i16> %a0, <8 x i16> zeroinitializer)
ret <8 x i16> %1
@@ -110,8 +99,7 @@ define <8 x i16> @zero_smulh_v8i16(<8 x i16> %a0) {
define <8 x i16> @zero_smulh_v8i16_commute(<8 x i16> %a0) {
; CHECK-LABEL: @zero_smulh_v8i16_commute(
-; CHECK-NEXT: [[TMP1:%.*]] = call <8 x i16> @llvm.smulh.v8i16(<8 x i16> [[A0:%.*]], <8 x i16> zeroinitializer)
-; CHECK-NEXT: ret <8 x i16> [[TMP1]]
+; CHECK-NEXT: ret <8 x i16> zeroinitializer
;
%1 = call <8 x i16> @llvm.smulh.v8i16(<8 x i16> zeroinitializer, <8 x i16> %a0)
ret <8 x i16> %1
@@ -119,8 +107,7 @@ define <8 x i16> @zero_smulh_v8i16_commute(<8 x i16> %a0) {
define <16 x i16> @zero_smulh_v16i16(<16 x i16> %a0) {
; CHECK-LABEL: @zero_smulh_v16i16(
-; CHECK-NEXT: [[TMP1:%.*]] = call <16 x i16> @llvm.smulh.v16i16(<16 x i16> [[A0:%.*]], <16 x i16> zeroinitializer)
-; CHECK-NEXT: ret <16 x i16> [[TMP1]]
+; CHECK-NEXT: ret <16 x i16> zeroinitializer
;
%1 = call <16 x i16> @llvm.smulh.v16i16(<16 x i16> %a0, <16 x i16> zeroinitializer)
ret <16 x i16> %1
@@ -128,8 +115,7 @@ define <16 x i16> @zero_smulh_v16i16(<16 x i16> %a0) {
define <16 x i16> @zero_smulh_v16i16_commute(<16 x i16> %a0) {
; CHECK-LABEL: @zero_smulh_v16i16_commute(
-; CHECK-NEXT: [[TMP1:%.*]] = call <16 x i16> @llvm.smulh.v16i16(<16 x i16> [[A0:%.*]], <16 x i16> zeroinitializer)
-; CHECK-NEXT: ret <16 x i16> [[TMP1]]
+; CHECK-NEXT: ret <16 x i16> zeroinitializer
;
%1 = call <16 x i16> @llvm.smulh.v16i16(<16 x i16> zeroinitializer, <16 x i16> %a0)
ret <16 x i16> %1
@@ -137,8 +123,7 @@ define <16 x i16> @zero_smulh_v16i16_commute(<16 x i16> %a0) {
define <32 x i16> @zero_smulh_v32i16(<32 x i16> %a0) {
; CHECK-LABEL: @zero_smulh_v32i16(
-; CHECK-NEXT: [[TMP1:%.*]] = call <32 x i16> @llvm.smulh.v32i16(<32 x i16> [[A0:%.*]], <32 x i16> zeroinitializer)
-; CHECK-NEXT: ret <32 x i16> [[TMP1]]
+; CHECK-NEXT: ret <32 x i16> zeroinitializer
;
%1 = call <32 x i16> @llvm.smulh.v32i16(<32 x i16> %a0, <32 x i16> zeroinitializer)
ret <32 x i16> %1
@@ -146,8 +131,7 @@ define <32 x i16> @zero_smulh_v32i16(<32 x i16> %a0) {
define <32 x i16> @zero_smulh_v32i16_commute(<32 x i16> %a0) {
; CHECK-LABEL: @zero_smulh_v32i16_commute(
-; CHECK-NEXT: [[TMP1:%.*]] = call <32 x i16> @llvm.smulh.v32i16(<32 x i16> [[A0:%.*]], <32 x i16> zeroinitializer)
-; CHECK-NEXT: ret <32 x i16> [[TMP1]]
+; CHECK-NEXT: ret <32 x i16> zeroinitializer
;
%1 = call <32 x i16> @llvm.smulh.v32i16(<32 x i16> zeroinitializer, <32 x i16> %a0)
ret <32 x i16> %1
@@ -159,7 +143,7 @@ define <32 x i16> @zero_smulh_v32i16_commute(<32 x i16> %a0) {
define i32 @one_smulh_i32(i32 %a0) {
; CHECK-LABEL: @one_smulh_i32(
-; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.smulh.i32(i32 [[A0:%.*]], i32 1)
+; CHECK-NEXT: [[TMP1:%.*]] = ashr i32 [[A0:%.*]], 31
; CHECK-NEXT: ret i32 [[TMP1]]
;
%1 = call i32 @llvm.smulh.i32(i32 %a0, i32 1)
@@ -168,7 +152,7 @@ define i32 @one_smulh_i32(i32 %a0) {
define i32 @one_smulh_i32_commute(i32 %a0) {
; CHECK-LABEL: @one_smulh_i32_commute(
-; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.smulh.i32(i32 [[A0:%.*]], i32 1)
+; CHECK-NEXT: [[TMP1:%.*]] = ashr i32 [[A0:%.*]], 31
; CHECK-NEXT: ret i32 [[TMP1]]
;
%1 = call i32 @llvm.smulh.i32(i32 1, i32 %a0)
@@ -177,7 +161,7 @@ define i32 @one_smulh_i32_commute(i32 %a0) {
define <8 x i16> @one_smulh_v8i16(<8 x i16> %a0) {
; CHECK-LABEL: @one_smulh_v8i16(
-; CHECK-NEXT: [[TMP1:%.*]] = call <8 x i16> @llvm.smulh.v8i16(<8 x i16> [[A0:%.*]], <8 x i16> splat (i16 1))
+; CHECK-NEXT: [[TMP1:%.*]] = ashr <8 x i16> [[A0:%.*]], splat (i16 15)
; CHECK-NEXT: ret <8 x i16> [[TMP1]]
;
%1 = call <8 x i16> @llvm.smulh.v8i16(<8 x i16> %a0, <8 x i16> <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>)
@@ -186,7 +170,7 @@ define <8 x i16> @one_smulh_v8i16(<8 x i16> %a0) {
define <8 x i16> @one_smulh_v8i16_commute(<8 x i16> %a0) {
; CHECK-LABEL: @one_smulh_v8i16_commute(
-; CHECK-NEXT: [[TMP1:%.*]] = call <8 x i16> @llvm.smulh.v8i16(<8 x i16> [[A0:%.*]], <8 x i16> splat (i16 1))
+; CHECK-NEXT: [[TMP1:%.*]] = ashr <8 x i16> [[A0:%.*]], splat (i16 15)
; CHECK-NEXT: ret <8 x i16> [[TMP1]]
;
%1 = call <8 x i16> @llvm.smulh.v8i16(<8 x i16> <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>, <8 x i16> %a0)
@@ -195,7 +179,7 @@ define <8 x i16> @one_smulh_v8i16_commute(<8 x i16> %a0) {
define <16 x i16> @one_smulh_v16i16(<16 x i16> %a0) {
; CHECK-LABEL: @one_smulh_v16i16(
-; CHECK-NEXT: [[TMP1:%.*]] = call <16 x i16> @llvm.smulh.v16i16(<16 x i16> [[A0:%.*]], <16 x i16> splat (i16 1))
+; CHECK-NEXT: [[TMP1:%.*]] = ashr <16 x i16> [[A0:%.*]], splat (i16 15)
; CHECK-NEXT: ret <16 x i16> [[TMP1]]
;
%1 = call <16 x i16> @llvm.smulh.v16i16(<16 x i16> %a0, <16 x i16> <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>)
@@ -204,7 +188,7 @@ define <16 x i16> @one_smulh_v16i16(<16 x i16> %a0) {
define <16 x i16> @one_smulh_v16i16_commute(<16 x i16> %a0) {
; CHECK-LABEL: @one_smulh_v16i16_commute(
-; CHECK-NEXT: [[TMP1:%.*]] = call <16 x i16> @llvm.smulh.v16i16(<16 x i16> [[A0:%.*]], <16 x i16> splat (i16 1))
+; CHECK-NEXT: [[TMP1:%.*]] = ashr <16 x i16> [[A0:%.*]], splat (i16 15)
; CHECK-NEXT: ret <16 x i16> [[TMP1]]
;
%1 = call <16 x i16> @llvm.smulh.v16i16(<16 x i16> <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>, <16 x i16> %a0)
@@ -213,7 +197,7 @@ define <16 x i16> @one_smulh_v16i16_commute(<16 x i16> %a0) {
define <32 x i16> @one_smulh_v32i16(<32 x i16> %a0) {
; CHECK-LABEL: @one_smulh_v32i16(
-; CHECK-NEXT: [[TMP1:%.*]] = call <32 x i16> @llvm.smulh.v32i16(<32 x i16> [[A0:%.*]], <32 x i16> splat (i16 1))
+; CHECK-NEXT: [[TMP1:%.*]] = ashr <32 x i16> [[A0:%.*]], splat (i16 15)
; CHECK-NEXT: ret <32 x i16> [[TMP1]]
;
%1 = call <32 x i16> @llvm.smulh.v32i16(<32 x i16> %a0, <32 x i16> <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>)
@@ -222,7 +206,7 @@ define <32 x i16> @one_smulh_v32i16(<32 x i16> %a0) {
define <32 x i16> @one_smulh_v32i16_commute(<32 x i16> %a0) {
; CHECK-LABEL: @one_smulh_v32i16_commute(
-; CHECK-NEXT: [[TMP1:%.*]] = call <32 x i16> @llvm.smulh.v32i16(<32 x i16> [[A0:%.*]], <32 x i16> splat (i16 1))
+; CHECK-NEXT: [[TMP1:%.*]] = ashr <32 x i16> [[A0:%.*]], splat (i16 15)
; CHECK-NEXT: ret <32 x i16> [[TMP1]]
;
%1 = call <32 x i16> @llvm.smulh.v32i16(<32 x i16> <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>, <32 x i16> %a0)
diff --git a/llvm/test/Transforms/InstCombine/umulh.ll b/llvm/test/Transforms/InstCombine/umulh.ll
index ccc21e603d69a..4ae74cdd1abd2 100644
--- a/llvm/test/Transforms/InstCombine/umulh.ll
+++ b/llvm/test/Transforms/InstCombine/umulh.ll
@@ -7,8 +7,7 @@
define i32 @undef_umulh_i32(i32 %a0) {
; CHECK-LABEL: @undef_umulh_i32(
-; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umulh.i32(i32 [[A0:%.*]], i32 undef)
-; CHECK-NEXT: ret i32 [[TMP1]]
+; CHECK-NEXT: ret i32 0
;
%1 = call i32 @llvm.umulh.i32(i32 %a0, i32 undef)
ret i32 %1
@@ -16,8 +15,7 @@ define i32 @undef_umulh_i32(i32 %a0) {
define i32 @undef_umulh_i32_commute(i32 %a0) {
; CHECK-LABEL: @undef_umulh_i32_commute(
-; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umulh.i32(i32 [[A0:%.*]], i32 undef)
-; CHECK-NEXT: ret i32 [[TMP1]]
+; CHECK-NEXT: ret i32 0
;
%1 = call i32 @llvm.umulh.i32(i32 undef, i32 %a0)
ret i32 %1
@@ -25,8 +23,7 @@ define i32 @undef_umulh_i32_commute(i32 %a0) {
define <8 x i16> @undef_umulh_v8i16(<8 x i16> %a0) {
; CHECK-LABEL: @undef_umulh_v8i16(
-; CHECK-NEXT: [[TMP1:%.*]] = call <8 x i16> @llvm.umulh.v8i16(<8 x i16> [[A0:%.*]], <8 x i16> undef)
-; CHECK-NEXT: ret <8 x i16> [[TMP1]]
+; CHECK-NEXT: ret <8 x i16> zeroinitializer
;
%1 = call <8 x i16> @llvm.umulh.v8i16(<8 x i16> %a0, <8 x i16> undef)
ret <8 x i16> %1
@@ -34,8 +31,7 @@ define <8 x i16> @undef_umulh_v8i16(<8 x i16> %a0) {
define <8 x i16> @undef_umulh_v8i16_commute(<8 x i16> %a0) {
; CHECK-LABEL: @undef_umulh_v8i16_commute(
-; CHECK-NEXT: [[TMP1:%.*]] = call <8 x i16> @llvm.umulh.v8i16(<8 x i16> [[A0:%.*]], <8 x i16> undef)
-; CHECK-NEXT: ret <8 x i16> [[TMP1]]
+; CHECK-NEXT: ret <8 x i16> zeroinitializer
;
%1 = call <8 x i16> @llvm.umulh.v8i16(<8 x i16> undef, <8 x i16> %a0)
ret <8 x i16> %1
@@ -43,8 +39,7 @@ define <8 x i16> @undef_umulh_v8i16_commute(<8 x i16> %a0) {
define <16 x i16> @undef_umulh_v16i16(<16 x i16> %a0) {
; CHECK-LABEL: @undef_umulh_v16i16(
-; CHECK-NEXT: [[TMP1:%.*]] = call <16 x i16> @llvm.umulh.v16i16(<16 x i16> [[A0:%.*]], <16 x i16> undef)
-; CHECK-NEXT: ret <16 x i16> [[TMP1]]
+; CHECK-NEXT: ret <16 x i16> zeroinitializer
;
%1 = call <16 x i16> @llvm.umulh.v16i16(<16 x i16> %a0, <16 x i16> undef)
ret <16 x i16> %1
@@ -52,8 +47,7 @@ define <16 x i16> @undef_umulh_v16i16(<16 x i16> %a0) {
define <16 x i16> @undef_umulh_v16i16_commute(<16 x i16> %a0) {
; CHECK-LABEL: @undef_umulh_v16i16_commute(
-; CHECK-NEXT: [[TMP1:%.*]] = call <16 x i16> @llvm.umulh.v16i16(<16 x i16> [[A0:%.*]], <16 x i16> undef)
-; CHECK-NEXT: ret <16 x i16> [[TMP1]]
+; CHECK-NEXT: ret <16 x i16> zeroinitializer
;
%1 = call <16 x i16> @llvm.umulh.v16i16(<16 x i16> undef, <16 x i16> %a0)
ret <16 x i16> %1
@@ -61,8 +55,7 @@ define <16 x i16> @undef_umulh_v16i16_commute(<16 x i16> %a0) {
define <32 x i16> @undef_umulh_v32i16(<32 x i16> %a0) {
; CHECK-LABEL: @undef_umulh_v32i16(
-; CHECK-NEXT: [[TMP1:%.*]] = call <32 x i16> @llvm.umulh.v32i16(<32 x i16> [[A0:%.*]], <32 x i16> undef)
-; CHECK-NEXT: ret <32 x i16> [[TMP1]]
+; CHECK-NEXT: ret <32 x i16> zeroinitializer
;
%1 = call <32 x i16> @llvm.umulh.v32i16(<32 x i16> %a0, <32 x i16> undef)
ret <32 x i16> %1
@@ -70,8 +63,7 @@ define <32 x i16> @undef_umulh_v32i16(<32 x i16> %a0) {
define <32 x i16> @undef_umulh_v32i16_commute(<32 x i16> %a0) {
; CHECK-LABEL: @undef_umulh_v32i16_commute(
-; CHECK-NEXT: [[TMP1:%.*]] = call <32 x i16> @llvm.umulh.v32i16(<32 x i16> [[A0:%.*]], <32 x i16> undef)
-; CHECK-NEXT: ret <32 x i16> [[TMP1]]
+; CHECK-NEXT: ret <32 x i16> zeroinitializer
;
%1 = call <32 x i16> @llvm.umulh.v32i16(<32 x i16> undef, <32 x i16> %a0)
ret <32 x i16> %1
@@ -83,8 +75,7 @@ define <32 x i16> @undef_umulh_v32i16_commute(<32 x i16> %a0) {
define i32 @zero_umulh_i32(i32 %a0) {
; CHECK-LABEL: @zero_umulh_i32(
-; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umulh.i32(i32 [[A0:%.*]], i32 0)
-; CHECK-NEXT: ret i32 [[TMP1]]
+; CHECK-NEXT: ret i32 0
;
%1 = call i32 @llvm.umulh.i32(i32 %a0, i32 zeroinitializer)
ret i32 %1
@@ -92,8 +83,7 @@ define i32 @zero_umulh_i32(i32 %a0) {
define i32 @zero_umulh_i32_commute(i32 %a0) {
; CHECK-LABEL: @zero_umulh_i32_commute(
-; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umulh.i32(i32 [[A0:%.*]], i32 0)
-; CHECK-NEXT: ret i32 [[TMP1]]
+; CHECK-NEXT: ret i32 0
;
%1 = call i32 @llvm.umulh.i32(i32 zeroinitializer, i32 %a0)
ret i32 %1
@@ -101,8 +91,7 @@ define i32 @zero_umulh_i32_commute(i32 %a0) {
define <8 x i16> @zero_umulh_v8i16(<8 x i16> %a0) {
; CHECK-LABEL: @zero_umulh_v8i16(
-; CHECK-NEXT: [[TMP1:%.*]] = call <8 x i16> @llvm.umulh.v8i16(<8 x i16> [[A0:%.*]], <8 x i16> zeroinitializer)
-; CHECK-NEXT: ret <8 x i16> [[TMP1]]
+; CHECK-NEXT: ret <8 x i16> zeroinitializer
;
%1 = call <8 x i16> @llvm.umulh.v8i16(<8 x i16> %a0, <8 x i16> zeroinitializer)
ret <8 x i16> %1
@@ -110,8 +99,7 @@ define <8 x i16> @zero_umulh_v8i16(<8 x i16> %a0) {
define <8 x i16> @zero_umulh_v8i16_commute(<8 x i16> %a0) {
; CHECK-LABEL: @zero_umulh_v8i16_commute(
-; CHECK-NEXT: [[TMP1:%.*]] = call <8 x i16> @llvm.umulh.v8i16(<8 x i16> [[A0:%.*]], <8 x i16> zeroinitializer)
-; CHECK-NEXT: ret <8 x i16> [[TMP1]]
+; CHECK-NEXT: ret <8 x i16> zeroinitializer
;
%1 = call <8 x i16> @llvm.umulh.v8i16(<8 x i16> zeroinitializer, <8 x i16> %a0)
ret <8 x i16> %1
@@ -119,8 +107,7 @@ define <8 x i16> @zero_umulh_v8i16_commute(<8 x i16> %a0) {
define <16 x i16> @zero_umulh_v16i16(<16 x i16> %a0) {
; CHECK-LABEL: @zero_umulh_v16i16(
-; CHECK-NEXT: [[TMP1:%.*]] = call <16 x i16> @llvm.umulh.v16i16(<16 x i16> [[A0:%.*]], <16 x i16> zeroinitializer)
-; CHECK-NEXT: ret <16 x i16> [[TMP1]]
+; CHECK-NEXT: ret <16 x i16> zeroinitializer
;
%1 = call <16 x i16> @llvm.umulh.v16i16(<16 x i16> %a0, <16 x i16> zeroinitializer)
ret <16 x i16> %1
@@ -128,8 +115,7 @@ define <16 x i16> @zero_umulh_v16i16(<16 x i16> %a0) {
define <16 x i16> @zero_umulh_v16i16_commute(<16 x i16> %a0) {
; CHECK-LABEL: @zero_umulh_v16i16_commute(
-; CHECK-NEXT: [[TMP1:%.*]] = call <16 x i16> @llvm.umulh.v16i16(<16 x i16> [[A0:%.*]], <16 x i16> zeroinitializer)
-; CHECK-NEXT: ret <16 x i16> [[TMP1]]
+; CHECK-NEXT: ret <16 x i16> zeroinitializer
;
%1 = call <16 x i16> @llvm.umulh.v16i16(<16 x i16> zeroinitializer, <16 x i16> %a0)
ret <16 x i16> %1
@@ -137,8 +123,7 @@ define <16 x i16> @zero_umulh_v16i16_commute(<16 x i16> %a0) {
define <32 x i16> @zero_umulh_v32i16(<32 x i16> %a0) {
; CHECK-LABEL: @zero_umulh_v32i16(
-; CHECK-NEXT: [[TMP1:%.*]] = call <32 x i16> @llvm.umulh.v32i16(<32 x i16> [[A0:%.*]], <32 x i16> zeroinitializer)
-; CHECK-NEXT: ret <32 x i16> [[TMP1]]
+; CHECK-NEXT: ret <32 x i16> zeroinitializer
;
%1 = call <32 x i16> @llvm.umulh.v32i16(<32 x i16> %a0, <32 x i16> zeroinitializer)
ret <32 x i16> %1
@@ -146,8 +131,7 @@ define <32 x i16> @zero_umulh_v32i16(<32 x i16> %a0) {
define <32 x i16> @zero_umulh_v32i16_commute(<32 x i16> %a0) {
; CHECK-LABEL: @zero_umulh_v32i16_commute(
-; CHECK-NEXT: [[TMP1:%.*]] = call <32 x i16> @llvm.umulh.v32i16(<32 x i16> [[A0:%.*]], <32 x i16> zeroinitializer)
-; CHECK-NEXT: ret <32 x i16> [[TMP1]]
+; CHECK-NEXT: ret <32 x i16> zeroinitializer
;
%1 = call <32 x i16> @llvm.umulh.v32i16(<32 x i16> zeroinitializer, <32 x i16> %a0)
ret <32 x i16> %1
@@ -159,8 +143,7 @@ define <32 x i16> @zero_umulh_v32i16_commute(<32 x i16> %a0) {
define i32 @one_umulh_i32(i32 %a0) {
; CHECK-LABEL: @one_umulh_i32(
-; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umulh.i32(i32 [[A0:%.*]], i32 1)
-; CHECK-NEXT: ret i32 [[TMP1]]
+; CHECK-NEXT: ret i32 0
;
%1 = call i32 @llvm.umulh.i32(i32 %a0, i32 1)
ret i32 %1
@@ -168,8 +151,7 @@ define i32 @one_umulh_i32(i32 %a0) {
define i32 @one_umulh_i32_commute(i32 %a0) {
; CHECK-LABEL: @one_umulh_i32_commute(
-; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umulh.i32(i32 [[A0:%.*]], i32 1)
-; CHECK-NEXT: ret i32 [[TMP1]]
+; CHECK-NEXT: ret i32 0
;
%1 = call i32 @llvm.umulh.i32(i32 1, i32 %a0)
ret i32 %1
@@ -177,8 +159,7 @@ define i32 @one_umulh_i32_commute(i32 %a0) {
define <8 x i16> @one_umulh_v8i16(<8 x i16> %a0) {
; CHECK-LABEL: @one_umulh_v8i16(
-; CHECK-NEXT: [[TMP1:%.*]] = call <8 x i16> @llvm.umulh.v8i16(<8 x i16> [[A0:%.*]], <8 x i16> splat (i16 1))
-; CHECK-NEXT: ret <8 x i16> [[TMP1]]
+; CHECK-NEXT: ret <8 x i16> zeroinitializer
;
%1 = call <8 x i16> @llvm.umulh.v8i16(<8 x i16> %a0, <8 x i16> <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>)
ret <8 x i16> %1
@@ -186,8 +167,7 @@ define <8 x i16> @one_umulh_v8i16(<8 x i16> %a0) {
define <8 x i16> @one_umulh_v8i16_commute(<8 x i16> %a0) {
; CHECK-LABEL: @one_umulh_v8i16_commute(
-; CHECK-NEXT: [[TMP1:%.*]] = call <8 x i16> @llvm.umulh.v8i16(<8 x i16> [[A0:%.*]], <8 x i16> splat (i16 1))
-; CHECK-NEXT: ret <8 x i16> [[TMP1]]
+; CHECK-NEXT: ret <8 x i16> zeroinitializer
;
%1 = call <8 x i16> @llvm.umulh.v8i16(<8 x i16> <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>, <8 x i16> %a0)
ret <8 x i16> %1
@@ -195,8 +175,7 @@ define <8 x i16> @one_umulh_v8i16_commute(<8 x i16> %a0) {
define <16 x i16> @one_umulh_v16i16(<16 x i16> %a0) {
; CHECK-LABEL: @one_umulh_v16i16(
-; CHECK-NEXT: [[TMP1:%.*]] = call <16 x i16> @llvm.umulh.v16i16(<16 x i16> [[A0:%.*]], <16 x i16> splat (i16 1))
-; CHECK-NEXT: ret <16 x i16> [[TMP1]]
+; CHECK-NEXT: ret <16 x i16> zeroinitializer
;
%1 = call <16 x i16> @llvm.umulh.v16i16(<16 x i16> %a0, <16 x i16> <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>)
ret <16 x i16> %1
@@ -204,8 +183,7 @@ define <16 x i16> @one_umulh_v16i16(<16 x i16> %a0) {
define <16 x i16> @one_umulh_v16i16_commute(<16 x i16> %a0) {
; CHECK-LABEL: @one_umulh_v16i16_commute(
-; CHECK-NEXT: [[TMP1:%.*]] = call <16 x i16> @llvm.umulh.v16i16(<16 x i16> [[A0:%.*]], <16 x i16> splat (i16 1))
-; CHECK-NEXT: ret <16 x i16> [[TMP1]]
+; CHECK-NEXT: ret <16 x i16> zeroinitializer
;
%1 = call <16 x i16> @llvm.umulh.v16i16(<16 x i16> <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>, <16 x i16> %a0)
ret <16 x i16> %1
@@ -213,8 +191,7 @@ define <16 x i16> @one_umulh_v16i16_commute(<16 x i16> %a0) {
define <32 x i16> @one_umulh_v32i16(<32 x i16> %a0) {
; CHECK-LABEL: @one_umulh_v32i16(
-; CHECK-NEXT: [[TMP1:%.*]] = call <32 x i16> @llvm.umulh.v32i16(<32 x i16> [[A0:%.*]], <32 x i16> splat (i16 1))
-; CHECK-NEXT: ret <32 x i16> [[TMP1]]
+; CHECK-NEXT: ret <32 x i16> zeroinitializer
;
%1 = call <32 x i16> @llvm.umulh.v32i16(<32 x i16> %a0, <32 x i16> <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>)
ret <32 x i16> %1
@@ -222,8 +199,7 @@ define <32 x i16> @one_umulh_v32i16(<32 x i16> %a0) {
define <32 x i16> @one_umulh_v32i16_commute(<32 x i16> %a0) {
; CHECK-LABEL: @one_umulh_v32i16_commute(
-; CHECK-NEXT: [[TMP1:%.*]] = call <32 x i16> @llvm.umulh.v32i16(<32 x i16> [[A0:%.*]], <32 x i16> splat (i16 1))
-; CHECK-NEXT: ret <32 x i16> [[TMP1]]
+; CHECK-NEXT: ret <32 x i16> zeroinitializer
;
%1 = call <32 x i16> @llvm.umulh.v32i16(<32 x i16> <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>, <32 x i16> %a0)
ret <32 x i16> %1
>From 22bb1248abc0844dd3b783d3a8e92e9969fe2f2c Mon Sep 17 00:00:00 2001
From: Simon Pilgrim <llvm-dev at redking.me.uk>
Date: Tue, 29 Sep 2026 17:07:39 +0100
Subject: [PATCH 3/7] Move mulh folds to zero to InstSimplify
---
llvm/lib/Analysis/InstructionSimplify.cpp | 15 +++++++++++++
.../InstCombine/InstCombineCalls.cpp | 21 +++----------------
2 files changed, 18 insertions(+), 18 deletions(-)
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 4e91cb44c7a18..29172c96d587b 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -7130,6 +7130,21 @@ static Value *simplifyBinaryIntrinsic(Intrinsic::ID IID, Type *ReturnType,
break;
}
+ case Intrinsic::umulh:
+ // Multiply by one.
+ if (match(Op0, m_One()) || match(Op1, m_One()))
+ return Constant::getNullValue(ReturnType);
+ [[fallthrough]];
+ case Intrinsic::smulh:
+ // Multiply by undef -> zero (NOT undef!) as other arg could still be
+ // zero.
+ if (Q.isUndefValue(Op0) || Q.isUndefValue(Op1))
+ return Constant::getNullValue(ReturnType);
+
+ // Multiply by zero.
+ if (match(Op0, m_Zero()) || match(Op1, m_Zero()))
+ return Constant::getNullValue(ReturnType);
+ break;
case Intrinsic::usub_with_overflow:
case Intrinsic::ssub_with_overflow:
// X - X -> { 0, false }
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index 8757dc169583d..46afdcd36c778 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -2883,31 +2883,16 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
break;
}
- case Intrinsic::smulh:
- case Intrinsic::umulh: {
+ case Intrinsic::smulh: {
Value *Arg0 = II->getArgOperand(0);
Value *Arg1 = II->getArgOperand(1);
- bool IsSigned = IID == Intrinsic::smulh;
unsigned BitWidth = II->getType()->getScalarSizeInBits();
- // Multiply by undef -> zero (NOT undef!) as other arg could still be
- // zero.
- if (isa<UndefValue>(Arg0) || isa<UndefValue>(Arg1))
- return replaceInstUsesWith(CI, ConstantInt::getNullValue(II->getType()));
-
- // Multiply by zero.
- if (match(Arg0, m_Zero()) || match(Arg1, m_Zero()))
- return replaceInstUsesWith(CI, ConstantInt::getNullValue(II->getType()));
-
// Multiply by one.
if (match(Arg0, m_One()))
- return replaceInstUsesWith(
- CI, IsSigned ? Builder.CreateAShr(Arg1, BitWidth - 1)
- : ConstantInt::getNullValue(II->getType()));
+ return replaceInstUsesWith(CI, Builder.CreateAShr(Arg1, BitWidth - 1));
if (match(Arg1, m_One()))
- return replaceInstUsesWith(
- CI, IsSigned ? Builder.CreateAShr(Arg0, BitWidth - 1)
- : ConstantInt::getNullValue(II->getType()));
+ return replaceInstUsesWith(CI, Builder.CreateAShr(Arg0, BitWidth - 1));
break;
}
>From 181fbfa12e73d295940960e1b901f422505ed342 Mon Sep 17 00:00:00 2001
From: Simon Pilgrim <llvm-dev at redking.me.uk>
Date: Thu, 1 Oct 2026 09:43:21 +0100
Subject: [PATCH 4/7] Avoid vector type duplication - made sense for x86
intrinsics, but not generics
---
llvm/test/Transforms/InstCombine/smulh.ll | 220 ++++------------------
llvm/test/Transforms/InstCombine/umulh.ll | 138 +++-----------
2 files changed, 55 insertions(+), 303 deletions(-)
diff --git a/llvm/test/Transforms/InstCombine/smulh.ll b/llvm/test/Transforms/InstCombine/smulh.ll
index f1e7632942afd..f7932f122761b 100644
--- a/llvm/test/Transforms/InstCombine/smulh.ll
+++ b/llvm/test/Transforms/InstCombine/smulh.ll
@@ -29,44 +29,12 @@ define <8 x i16> @undef_smulh_v8i16(<8 x i16> %a0) {
ret <8 x i16> %1
}
-define <8 x i16> @undef_smulh_v8i16_commute(<8 x i16> %a0) {
-; CHECK-LABEL: @undef_smulh_v8i16_commute(
-; CHECK-NEXT: ret <8 x i16> zeroinitializer
-;
- %1 = call <8 x i16> @llvm.smulh.v8i16(<8 x i16> undef, <8 x i16> %a0)
- ret <8 x i16> %1
-}
-
-define <16 x i16> @undef_smulh_v16i16(<16 x i16> %a0) {
-; CHECK-LABEL: @undef_smulh_v16i16(
-; CHECK-NEXT: ret <16 x i16> zeroinitializer
-;
- %1 = call <16 x i16> @llvm.smulh.v16i16(<16 x i16> %a0, <16 x i16> undef)
- ret <16 x i16> %1
-}
-
-define <16 x i16> @undef_smulh_v16i16_commute(<16 x i16> %a0) {
-; CHECK-LABEL: @undef_smulh_v16i16_commute(
-; CHECK-NEXT: ret <16 x i16> zeroinitializer
+define <32 x i8> @undef_smulh_v32i8_commute(<32 x i8> %a0) {
+; CHECK-LABEL: @undef_smulh_v32i8_commute(
+; CHECK-NEXT: ret <32 x i8> zeroinitializer
;
- %1 = call <16 x i16> @llvm.smulh.v16i16(<16 x i16> undef, <16 x i16> %a0)
- ret <16 x i16> %1
-}
-
-define <32 x i16> @undef_smulh_v32i16(<32 x i16> %a0) {
-; CHECK-LABEL: @undef_smulh_v32i16(
-; CHECK-NEXT: ret <32 x i16> zeroinitializer
-;
- %1 = call <32 x i16> @llvm.smulh.v32i16(<32 x i16> %a0, <32 x i16> undef)
- ret <32 x i16> %1
-}
-
-define <32 x i16> @undef_smulh_v32i16_commute(<32 x i16> %a0) {
-; CHECK-LABEL: @undef_smulh_v32i16_commute(
-; CHECK-NEXT: ret <32 x i16> zeroinitializer
-;
- %1 = call <32 x i16> @llvm.smulh.v32i16(<32 x i16> undef, <32 x i16> %a0)
- ret <32 x i16> %1
+ %1 = call <32 x i8> @llvm.smulh.v32i8(<32 x i8> undef, <32 x i8> %a0)
+ ret <32 x i8> %1
}
;
@@ -89,52 +57,20 @@ define i32 @zero_smulh_i32_commute(i32 %a0) {
ret i32 %1
}
-define <8 x i16> @zero_smulh_v8i16(<8 x i16> %a0) {
-; CHECK-LABEL: @zero_smulh_v8i16(
-; CHECK-NEXT: ret <8 x i16> zeroinitializer
+define <2 x i32> @zero_smulh_v2i32(<2 x i32> %a0) {
+; CHECK-LABEL: @zero_smulh_v2i32(
+; CHECK-NEXT: ret <2 x i32> zeroinitializer
;
- %1 = call <8 x i16> @llvm.smulh.v8i16(<8 x i16> %a0, <8 x i16> zeroinitializer)
- ret <8 x i16> %1
+ %1 = call <2 x i32> @llvm.smulh.v2i32(<2 x i32> %a0, <2 x i32> zeroinitializer)
+ ret <2 x i32> %1
}
-define <8 x i16> @zero_smulh_v8i16_commute(<8 x i16> %a0) {
-; CHECK-LABEL: @zero_smulh_v8i16_commute(
-; CHECK-NEXT: ret <8 x i16> zeroinitializer
+define <8 x i64> @zero_smulh_v8i64_commute(<8 x i64> %a0) {
+; CHECK-LABEL: @zero_smulh_v8i64_commute(
+; CHECK-NEXT: ret <8 x i64> zeroinitializer
;
- %1 = call <8 x i16> @llvm.smulh.v8i16(<8 x i16> zeroinitializer, <8 x i16> %a0)
- ret <8 x i16> %1
-}
-
-define <16 x i16> @zero_smulh_v16i16(<16 x i16> %a0) {
-; CHECK-LABEL: @zero_smulh_v16i16(
-; CHECK-NEXT: ret <16 x i16> zeroinitializer
-;
- %1 = call <16 x i16> @llvm.smulh.v16i16(<16 x i16> %a0, <16 x i16> zeroinitializer)
- ret <16 x i16> %1
-}
-
-define <16 x i16> @zero_smulh_v16i16_commute(<16 x i16> %a0) {
-; CHECK-LABEL: @zero_smulh_v16i16_commute(
-; CHECK-NEXT: ret <16 x i16> zeroinitializer
-;
- %1 = call <16 x i16> @llvm.smulh.v16i16(<16 x i16> zeroinitializer, <16 x i16> %a0)
- ret <16 x i16> %1
-}
-
-define <32 x i16> @zero_smulh_v32i16(<32 x i16> %a0) {
-; CHECK-LABEL: @zero_smulh_v32i16(
-; CHECK-NEXT: ret <32 x i16> zeroinitializer
-;
- %1 = call <32 x i16> @llvm.smulh.v32i16(<32 x i16> %a0, <32 x i16> zeroinitializer)
- ret <32 x i16> %1
-}
-
-define <32 x i16> @zero_smulh_v32i16_commute(<32 x i16> %a0) {
-; CHECK-LABEL: @zero_smulh_v32i16_commute(
-; CHECK-NEXT: ret <32 x i16> zeroinitializer
-;
- %1 = call <32 x i16> @llvm.smulh.v32i16(<32 x i16> zeroinitializer, <32 x i16> %a0)
- ret <32 x i16> %1
+ %1 = call <8 x i64> @llvm.smulh.v8i64(<8 x i64> zeroinitializer, <8 x i64> %a0)
+ ret <8 x i64> %1
}
;
@@ -159,31 +95,13 @@ define i32 @one_smulh_i32_commute(i32 %a0) {
ret i32 %1
}
-define <8 x i16> @one_smulh_v8i16(<8 x i16> %a0) {
-; CHECK-LABEL: @one_smulh_v8i16(
-; CHECK-NEXT: [[TMP1:%.*]] = ashr <8 x i16> [[A0:%.*]], splat (i16 15)
-; CHECK-NEXT: ret <8 x i16> [[TMP1]]
+define <8 x i8> @one_smulh_v8i8(<8 x i8> %a0) {
+; CHECK-LABEL: @one_smulh_v8i8(
+; CHECK-NEXT: [[TMP1:%.*]] = ashr <8 x i8> [[A0:%.*]], splat (i8 7)
+; CHECK-NEXT: ret <8 x i8> [[TMP1]]
;
- %1 = call <8 x i16> @llvm.smulh.v8i16(<8 x i16> %a0, <8 x i16> <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>)
- ret <8 x i16> %1
-}
-
-define <8 x i16> @one_smulh_v8i16_commute(<8 x i16> %a0) {
-; CHECK-LABEL: @one_smulh_v8i16_commute(
-; CHECK-NEXT: [[TMP1:%.*]] = ashr <8 x i16> [[A0:%.*]], splat (i16 15)
-; CHECK-NEXT: ret <8 x i16> [[TMP1]]
-;
- %1 = call <8 x i16> @llvm.smulh.v8i16(<8 x i16> <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>, <8 x i16> %a0)
- ret <8 x i16> %1
-}
-
-define <16 x i16> @one_smulh_v16i16(<16 x i16> %a0) {
-; CHECK-LABEL: @one_smulh_v16i16(
-; CHECK-NEXT: [[TMP1:%.*]] = ashr <16 x i16> [[A0:%.*]], splat (i16 15)
-; CHECK-NEXT: ret <16 x i16> [[TMP1]]
-;
- %1 = call <16 x i16> @llvm.smulh.v16i16(<16 x i16> %a0, <16 x i16> <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>)
- ret <16 x i16> %1
+ %1 = call <8 x i8> @llvm.smulh.v8i8(<8 x i8> %a0, <8 x i8> splat (i8 1))
+ ret <8 x i8> %1
}
define <16 x i16> @one_smulh_v16i16_commute(<16 x i16> %a0) {
@@ -191,28 +109,10 @@ define <16 x i16> @one_smulh_v16i16_commute(<16 x i16> %a0) {
; CHECK-NEXT: [[TMP1:%.*]] = ashr <16 x i16> [[A0:%.*]], splat (i16 15)
; CHECK-NEXT: ret <16 x i16> [[TMP1]]
;
- %1 = call <16 x i16> @llvm.smulh.v16i16(<16 x i16> <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>, <16 x i16> %a0)
+ %1 = call <16 x i16> @llvm.smulh.v16i16(<16 x i16> splat (i16 1), <16 x i16> %a0)
ret <16 x i16> %1
}
-define <32 x i16> @one_smulh_v32i16(<32 x i16> %a0) {
-; CHECK-LABEL: @one_smulh_v32i16(
-; CHECK-NEXT: [[TMP1:%.*]] = ashr <32 x i16> [[A0:%.*]], splat (i16 15)
-; CHECK-NEXT: ret <32 x i16> [[TMP1]]
-;
- %1 = call <32 x i16> @llvm.smulh.v32i16(<32 x i16> %a0, <32 x i16> <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>)
- ret <32 x i16> %1
-}
-
-define <32 x i16> @one_smulh_v32i16_commute(<32 x i16> %a0) {
-; CHECK-LABEL: @one_smulh_v32i16_commute(
-; CHECK-NEXT: [[TMP1:%.*]] = ashr <32 x i16> [[A0:%.*]], splat (i16 15)
-; CHECK-NEXT: ret <32 x i16> [[TMP1]]
-;
- %1 = call <32 x i16> @llvm.smulh.v32i16(<32 x i16> <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>, <32 x i16> %a0)
- ret <32 x i16> %1
-}
-
;
; Constant Folding
;
@@ -253,49 +153,19 @@ define <32 x i16> @fold_smulh_v32i16() {
; Demanded Elts
;
-define <8 x i16> @elts_smulh_v8i16(<8 x i16> %a0, <8 x i16> %a1) {
-; CHECK-LABEL: @elts_smulh_v8i16(
-; CHECK-NEXT: [[A0:%.*]] = shufflevector <8 x i16> [[A2:%.*]], <8 x i16> poison, <8 x i32> <i32 0, i32 1, i32 7, i32 6, i32 5, i32 4, i32 3, i32 2>
-; CHECK-NEXT: [[A1:%.*]] = shufflevector <8 x i16> [[A3:%.*]], <8 x i16> poison, <8 x i32> <i32 0, i32 1, i32 3, i32 2, i32 5, i32 4, i32 7, i32 6>
-; CHECK-NEXT: [[TMP1:%.*]] = call <8 x i16> @llvm.smulh.v8i16(<8 x i16> [[A0]], <8 x i16> [[A1]])
-; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <8 x i16> [[TMP1]], <8 x i16> poison, <8 x i32> zeroinitializer
-; CHECK-NEXT: ret <8 x i16> [[TMP2]]
+define <8 x i64> @elts_smulh_v8i64(<8 x i64> %a0, <8 x i64> %a1) {
+; CHECK-LABEL: @elts_smulh_v8i64(
+; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <8 x i64> [[A0:%.*]], <8 x i64> poison, <8 x i32> <i32 0, i32 1, i32 7, i32 6, i32 5, i32 4, i32 3, i32 2>
+; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <8 x i64> [[A1:%.*]], <8 x i64> poison, <8 x i32> <i32 0, i32 1, i32 3, i32 2, i32 5, i32 4, i32 7, i32 6>
+; CHECK-NEXT: [[TMP3:%.*]] = call <8 x i64> @llvm.smulh.v8i64(<8 x i64> [[TMP1]], <8 x i64> [[TMP2]])
+; CHECK-NEXT: [[TMP4:%.*]] = shufflevector <8 x i64> [[TMP3]], <8 x i64> poison, <8 x i32> zeroinitializer
+; CHECK-NEXT: ret <8 x i64> [[TMP4]]
;
- %1 = shufflevector <8 x i16> %a0, <8 x i16> undef, <8 x i32> <i32 0, i32 1, i32 7, i32 6, i32 5, i32 4, i32 3, i32 2>
- %2 = shufflevector <8 x i16> %a1, <8 x i16> undef, <8 x i32> <i32 0, i32 1, i32 3, i32 2, i32 5, i32 4, i32 7, i32 6>
- %3 = call <8 x i16> @llvm.smulh.v8i16(<8 x i16> %1, <8 x i16> %2)
- %4 = shufflevector <8 x i16> %3, <8 x i16> poison, <8 x i32> zeroinitializer
- ret <8 x i16> %4
-}
-
-define <16 x i16> @elts_smulh_v16i16(<16 x i16> %a0, <16 x i16> %a1) {
-; CHECK-LABEL: @elts_smulh_v16i16(
-; CHECK-NEXT: [[A0:%.*]] = shufflevector <16 x i16> [[A2:%.*]], <16 x i16> poison, <16 x i32> <i32 0, i32 1, i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
-; CHECK-NEXT: [[A1:%.*]] = shufflevector <16 x i16> [[A3:%.*]], <16 x i16> poison, <16 x i32> <i32 0, i32 1, i32 3, i32 2, i32 5, i32 4, i32 7, i32 6, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
-; CHECK-NEXT: [[TMP1:%.*]] = call <16 x i16> @llvm.smulh.v16i16(<16 x i16> [[A0]], <16 x i16> [[A1]])
-; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <16 x i16> [[TMP1]], <16 x i16> poison, <16 x i32> zeroinitializer
-; CHECK-NEXT: ret <16 x i16> [[TMP2]]
-;
- %1 = shufflevector <16 x i16> %a0, <16 x i16> undef, <16 x i32> <i32 0, i32 1, i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
- %2 = shufflevector <16 x i16> %a1, <16 x i16> undef, <16 x i32> <i32 0, i32 1, i32 3, i32 2, i32 5, i32 4, i32 7, i32 6, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
- %3 = call <16 x i16> @llvm.smulh.v16i16(<16 x i16> %1, <16 x i16> %2)
- %4 = shufflevector <16 x i16> %3, <16 x i16> poison, <16 x i32> zeroinitializer
- ret <16 x i16> %4
-}
-
-define <32 x i16> @elts_smulh_v32i16(<32 x i16> %a0, <32 x i16> %a1) {
-; CHECK-LABEL: @elts_smulh_v32i16(
-; CHECK-NEXT: [[A0:%.*]] = shufflevector <32 x i16> [[A2:%.*]], <32 x i16> poison, <32 x i32> <i32 0, i32 1, i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>
-; CHECK-NEXT: [[A1:%.*]] = shufflevector <32 x i16> [[A3:%.*]], <32 x i16> poison, <32 x i32> <i32 0, i32 1, i32 3, i32 2, i32 5, i32 4, i32 7, i32 6, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>
-; CHECK-NEXT: [[TMP1:%.*]] = call <32 x i16> @llvm.smulh.v32i16(<32 x i16> [[A0]], <32 x i16> [[A1]])
-; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <32 x i16> [[TMP1]], <32 x i16> poison, <32 x i32> zeroinitializer
-; CHECK-NEXT: ret <32 x i16> [[TMP2]]
-;
- %1 = shufflevector <32 x i16> %a0, <32 x i16> undef, <32 x i32> <i32 0, i32 1, i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>
- %2 = shufflevector <32 x i16> %a1, <32 x i16> undef, <32 x i32> <i32 0, i32 1, i32 3, i32 2, i32 5, i32 4, i32 7, i32 6, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>
- %3 = call <32 x i16> @llvm.smulh.v32i16(<32 x i16> %1, <32 x i16> %2)
- %4 = shufflevector <32 x i16> %3, <32 x i16> poison, <32 x i32> zeroinitializer
- ret <32 x i16> %4
+ %1 = shufflevector <8 x i64> %a0, <8 x i64> undef, <8 x i32> <i32 0, i32 1, i32 7, i32 6, i32 5, i32 4, i32 3, i32 2>
+ %2 = shufflevector <8 x i64> %a1, <8 x i64> undef, <8 x i32> <i32 0, i32 1, i32 3, i32 2, i32 5, i32 4, i32 7, i32 6>
+ %3 = call <8 x i64> @llvm.smulh.v8i64(<8 x i64> %1, <8 x i64> %2)
+ %4 = shufflevector <8 x i64> %3, <8 x i64> poison, <8 x i32> zeroinitializer
+ ret <8 x i64> %4
}
;
@@ -312,25 +182,3 @@ define <8 x i16> @known_smulh_v8i16(<8 x i16> %a0, <8 x i16> %a1, <8 x i16> %a2)
%r = add <8 x i16> %m, %a2
ret <8 x i16> %r
}
-
-define <16 x i16> @known_smulh_v16i16(<16 x i16> %a0, <16 x i16> %a1, <16 x i16> %a2) {
-; CHECK-LABEL: @known_smulh_v16i16(
-; CHECK-NEXT: ret <16 x i16> [[A2:%.*]]
-;
- %x0 = lshr <16 x i16> %a0, <i16 8, i16 9, i16 10, i16 11, i16 12, i16 13, i16 14, i16 15, i16 8, i16 9, i16 10, i16 11, i16 12, i16 13, i16 14, i16 15>
- %x1 = and <16 x i16> %a1, <i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3>
- %m = tail call <16 x i16> @llvm.smulh.v16i16(<16 x i16> %x0, <16 x i16> %x1)
- %r = add <16 x i16> %m, %a2
- ret <16 x i16> %r
-}
-
-define <32 x i16> @known_smulh_v32i16(<32 x i16> %a0, <32 x i16> %a1, <32 x i16> %a2) {
-; CHECK-LABEL: @known_smulh_v32i16(
-; CHECK-NEXT: ret <32 x i16> [[A2:%.*]]
-;
- %x0 = lshr <32 x i16> %a0, <i16 8, i16 9, i16 10, i16 11, i16 12, i16 13, i16 14, i16 15, i16 8, i16 9, i16 10, i16 11, i16 12, i16 13, i16 14, i16 15, i16 8, i16 9, i16 10, i16 11, i16 12, i16 13, i16 14, i16 15, i16 8, i16 9, i16 10, i16 11, i16 12, i16 13, i16 14, i16 15>
- %x1 = and <32 x i16> %a1, <i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3>
- %m = tail call <32 x i16> @llvm.smulh.v32i16(<32 x i16> %x0, <32 x i16> %x1)
- %r = add <32 x i16> %m, %a2
- ret <32 x i16> %r
-}
diff --git a/llvm/test/Transforms/InstCombine/umulh.ll b/llvm/test/Transforms/InstCombine/umulh.ll
index 4ae74cdd1abd2..f58e74455f175 100644
--- a/llvm/test/Transforms/InstCombine/umulh.ll
+++ b/llvm/test/Transforms/InstCombine/umulh.ll
@@ -29,44 +29,12 @@ define <8 x i16> @undef_umulh_v8i16(<8 x i16> %a0) {
ret <8 x i16> %1
}
-define <8 x i16> @undef_umulh_v8i16_commute(<8 x i16> %a0) {
-; CHECK-LABEL: @undef_umulh_v8i16_commute(
-; CHECK-NEXT: ret <8 x i16> zeroinitializer
-;
- %1 = call <8 x i16> @llvm.umulh.v8i16(<8 x i16> undef, <8 x i16> %a0)
- ret <8 x i16> %1
-}
-
-define <16 x i16> @undef_umulh_v16i16(<16 x i16> %a0) {
-; CHECK-LABEL: @undef_umulh_v16i16(
-; CHECK-NEXT: ret <16 x i16> zeroinitializer
-;
- %1 = call <16 x i16> @llvm.umulh.v16i16(<16 x i16> %a0, <16 x i16> undef)
- ret <16 x i16> %1
-}
-
-define <16 x i16> @undef_umulh_v16i16_commute(<16 x i16> %a0) {
-; CHECK-LABEL: @undef_umulh_v16i16_commute(
-; CHECK-NEXT: ret <16 x i16> zeroinitializer
-;
- %1 = call <16 x i16> @llvm.umulh.v16i16(<16 x i16> undef, <16 x i16> %a0)
- ret <16 x i16> %1
-}
-
-define <32 x i16> @undef_umulh_v32i16(<32 x i16> %a0) {
-; CHECK-LABEL: @undef_umulh_v32i16(
-; CHECK-NEXT: ret <32 x i16> zeroinitializer
+define <32 x i8> @undef_umulh_v32i8_commute(<32 x i8> %a0) {
+; CHECK-LABEL: @undef_umulh_v32i8_commute(
+; CHECK-NEXT: ret <32 x i8> zeroinitializer
;
- %1 = call <32 x i16> @llvm.umulh.v32i16(<32 x i16> %a0, <32 x i16> undef)
- ret <32 x i16> %1
-}
-
-define <32 x i16> @undef_umulh_v32i16_commute(<32 x i16> %a0) {
-; CHECK-LABEL: @undef_umulh_v32i16_commute(
-; CHECK-NEXT: ret <32 x i16> zeroinitializer
-;
- %1 = call <32 x i16> @llvm.umulh.v32i16(<32 x i16> undef, <32 x i16> %a0)
- ret <32 x i16> %1
+ %1 = call <32 x i8> @llvm.umulh.v32i8(<32 x i8> undef, <32 x i8> %a0)
+ ret <32 x i8> %1
}
;
@@ -89,52 +57,20 @@ define i32 @zero_umulh_i32_commute(i32 %a0) {
ret i32 %1
}
-define <8 x i16> @zero_umulh_v8i16(<8 x i16> %a0) {
-; CHECK-LABEL: @zero_umulh_v8i16(
-; CHECK-NEXT: ret <8 x i16> zeroinitializer
-;
- %1 = call <8 x i16> @llvm.umulh.v8i16(<8 x i16> %a0, <8 x i16> zeroinitializer)
- ret <8 x i16> %1
-}
-
-define <8 x i16> @zero_umulh_v8i16_commute(<8 x i16> %a0) {
-; CHECK-LABEL: @zero_umulh_v8i16_commute(
-; CHECK-NEXT: ret <8 x i16> zeroinitializer
-;
- %1 = call <8 x i16> @llvm.umulh.v8i16(<8 x i16> zeroinitializer, <8 x i16> %a0)
- ret <8 x i16> %1
-}
-
-define <16 x i16> @zero_umulh_v16i16(<16 x i16> %a0) {
-; CHECK-LABEL: @zero_umulh_v16i16(
-; CHECK-NEXT: ret <16 x i16> zeroinitializer
-;
- %1 = call <16 x i16> @llvm.umulh.v16i16(<16 x i16> %a0, <16 x i16> zeroinitializer)
- ret <16 x i16> %1
-}
-
-define <16 x i16> @zero_umulh_v16i16_commute(<16 x i16> %a0) {
-; CHECK-LABEL: @zero_umulh_v16i16_commute(
-; CHECK-NEXT: ret <16 x i16> zeroinitializer
-;
- %1 = call <16 x i16> @llvm.umulh.v16i16(<16 x i16> zeroinitializer, <16 x i16> %a0)
- ret <16 x i16> %1
-}
-
-define <32 x i16> @zero_umulh_v32i16(<32 x i16> %a0) {
-; CHECK-LABEL: @zero_umulh_v32i16(
-; CHECK-NEXT: ret <32 x i16> zeroinitializer
+define <2 x i32> @zero_umulh_v2i32(<2 x i32> %a0) {
+; CHECK-LABEL: @zero_umulh_v2i32(
+; CHECK-NEXT: ret <2 x i32> zeroinitializer
;
- %1 = call <32 x i16> @llvm.umulh.v32i16(<32 x i16> %a0, <32 x i16> zeroinitializer)
- ret <32 x i16> %1
+ %1 = call <2 x i32> @llvm.umulh.v2i32(<2 x i32> %a0, <2 x i32> zeroinitializer)
+ ret <2 x i32> %1
}
-define <32 x i16> @zero_umulh_v32i16_commute(<32 x i16> %a0) {
-; CHECK-LABEL: @zero_umulh_v32i16_commute(
-; CHECK-NEXT: ret <32 x i16> zeroinitializer
+define <8 x i64> @zero_umulh_v8i64_commute(<8 x i64> %a0) {
+; CHECK-LABEL: @zero_umulh_v8i64_commute(
+; CHECK-NEXT: ret <8 x i64> zeroinitializer
;
- %1 = call <32 x i16> @llvm.umulh.v32i16(<32 x i16> zeroinitializer, <32 x i16> %a0)
- ret <32 x i16> %1
+ %1 = call <8 x i64> @llvm.umulh.v8i64(<8 x i64> zeroinitializer, <8 x i64> %a0)
+ ret <8 x i64> %1
}
;
@@ -157,54 +93,22 @@ define i32 @one_umulh_i32_commute(i32 %a0) {
ret i32 %1
}
-define <8 x i16> @one_umulh_v8i16(<8 x i16> %a0) {
-; CHECK-LABEL: @one_umulh_v8i16(
-; CHECK-NEXT: ret <8 x i16> zeroinitializer
+define <8 x i8> @one_umulh_v8i8(<8 x i8> %a0) {
+; CHECK-LABEL: @one_umulh_v8i8(
+; CHECK-NEXT: ret <8 x i8> zeroinitializer
;
- %1 = call <8 x i16> @llvm.umulh.v8i16(<8 x i16> %a0, <8 x i16> <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>)
- ret <8 x i16> %1
-}
-
-define <8 x i16> @one_umulh_v8i16_commute(<8 x i16> %a0) {
-; CHECK-LABEL: @one_umulh_v8i16_commute(
-; CHECK-NEXT: ret <8 x i16> zeroinitializer
-;
- %1 = call <8 x i16> @llvm.umulh.v8i16(<8 x i16> <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>, <8 x i16> %a0)
- ret <8 x i16> %1
-}
-
-define <16 x i16> @one_umulh_v16i16(<16 x i16> %a0) {
-; CHECK-LABEL: @one_umulh_v16i16(
-; CHECK-NEXT: ret <16 x i16> zeroinitializer
-;
- %1 = call <16 x i16> @llvm.umulh.v16i16(<16 x i16> %a0, <16 x i16> <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>)
- ret <16 x i16> %1
+ %1 = call <8 x i8> @llvm.umulh.v8i8(<8 x i8> %a0, <8 x i8> splat (i8 1))
+ ret <8 x i8> %1
}
define <16 x i16> @one_umulh_v16i16_commute(<16 x i16> %a0) {
; CHECK-LABEL: @one_umulh_v16i16_commute(
; CHECK-NEXT: ret <16 x i16> zeroinitializer
;
- %1 = call <16 x i16> @llvm.umulh.v16i16(<16 x i16> <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>, <16 x i16> %a0)
+ %1 = call <16 x i16> @llvm.umulh.v16i16(<16 x i16> splat (i16 1), <16 x i16> %a0)
ret <16 x i16> %1
}
-define <32 x i16> @one_umulh_v32i16(<32 x i16> %a0) {
-; CHECK-LABEL: @one_umulh_v32i16(
-; CHECK-NEXT: ret <32 x i16> zeroinitializer
-;
- %1 = call <32 x i16> @llvm.umulh.v32i16(<32 x i16> %a0, <32 x i16> <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>)
- ret <32 x i16> %1
-}
-
-define <32 x i16> @one_umulh_v32i16_commute(<32 x i16> %a0) {
-; CHECK-LABEL: @one_umulh_v32i16_commute(
-; CHECK-NEXT: ret <32 x i16> zeroinitializer
-;
- %1 = call <32 x i16> @llvm.umulh.v32i16(<32 x i16> <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>, <32 x i16> %a0)
- ret <32 x i16> %1
-}
-
;
; Constant Folding
;
>From 81cea113bd59df225ededec49d19d66c47efd68d Mon Sep 17 00:00:00 2001
From: Simon Pilgrim <llvm-dev at redking.me.uk>
Date: Thu, 1 Oct 2026 09:44:34 +0100
Subject: [PATCH 5/7] Add POSION test coverage
---
llvm/test/Transforms/InstCombine/smulh.ll | 36 +++++++++++++++++++++++
llvm/test/Transforms/InstCombine/umulh.ll | 36 +++++++++++++++++++++++
2 files changed, 72 insertions(+)
diff --git a/llvm/test/Transforms/InstCombine/smulh.ll b/llvm/test/Transforms/InstCombine/smulh.ll
index f7932f122761b..69085237e321a 100644
--- a/llvm/test/Transforms/InstCombine/smulh.ll
+++ b/llvm/test/Transforms/InstCombine/smulh.ll
@@ -37,6 +37,42 @@ define <32 x i8> @undef_smulh_v32i8_commute(<32 x i8> %a0) {
ret <32 x i8> %1
}
+;
+; POISON Elts
+;
+
+define i32 @poison_smulh_i32(i32 %a0) {
+; CHECK-LABEL: @poison_smulh_i32(
+; CHECK-NEXT: ret i32 0
+;
+ %1 = call i32 @llvm.smulh.i32(i32 %a0, i32 poison)
+ ret i32 %1
+}
+
+define i32 @poison_smulh_i32_commute(i32 %a0) {
+; CHECK-LABEL: @poison_smulh_i32_commute(
+; CHECK-NEXT: ret i32 0
+;
+ %1 = call i32 @llvm.smulh.i32(i32 poison, i32 %a0)
+ ret i32 %1
+}
+
+define <8 x i16> @poison_smulh_v8i16(<8 x i16> %a0) {
+; CHECK-LABEL: @poison_smulh_v8i16(
+; CHECK-NEXT: ret <8 x i16> zeroinitializer
+;
+ %1 = call <8 x i16> @llvm.smulh.v8i16(<8 x i16> %a0, <8 x i16> poison)
+ ret <8 x i16> %1
+}
+
+define <32 x i8> @poison_smulh_v32i8_commute(<32 x i8> %a0) {
+; CHECK-LABEL: @poison_smulh_v32i8_commute(
+; CHECK-NEXT: ret <32 x i8> zeroinitializer
+;
+ %1 = call <32 x i8> @llvm.smulh.v32i8(<32 x i8> poison, <32 x i8> %a0)
+ ret <32 x i8> %1
+}
+
;
; Zero Elts
;
diff --git a/llvm/test/Transforms/InstCombine/umulh.ll b/llvm/test/Transforms/InstCombine/umulh.ll
index f58e74455f175..c198b20ce364c 100644
--- a/llvm/test/Transforms/InstCombine/umulh.ll
+++ b/llvm/test/Transforms/InstCombine/umulh.ll
@@ -37,6 +37,42 @@ define <32 x i8> @undef_umulh_v32i8_commute(<32 x i8> %a0) {
ret <32 x i8> %1
}
+;
+; POISON Elts
+;
+
+define i32 @poison_umulh_i32(i32 %a0) {
+; CHECK-LABEL: @poison_umulh_i32(
+; CHECK-NEXT: ret i32 0
+;
+ %1 = call i32 @llvm.umulh.i32(i32 %a0, i32 poison)
+ ret i32 %1
+}
+
+define i32 @poison_umulh_i32_commute(i32 %a0) {
+; CHECK-LABEL: @poison_umulh_i32_commute(
+; CHECK-NEXT: ret i32 0
+;
+ %1 = call i32 @llvm.umulh.i32(i32 poison, i32 %a0)
+ ret i32 %1
+}
+
+define <8 x i16> @poison_umulh_v8i16(<8 x i16> %a0) {
+; CHECK-LABEL: @poison_umulh_v8i16(
+; CHECK-NEXT: ret <8 x i16> zeroinitializer
+;
+ %1 = call <8 x i16> @llvm.umulh.v8i16(<8 x i16> %a0, <8 x i16> poison)
+ ret <8 x i16> %1
+}
+
+define <32 x i8> @poison_umulh_v32i8_commute(<32 x i8> %a0) {
+; CHECK-LABEL: @poison_umulh_v32i8_commute(
+; CHECK-NEXT: ret <32 x i8> zeroinitializer
+;
+ %1 = call <32 x i8> @llvm.umulh.v32i8(<32 x i8> poison, <32 x i8> %a0)
+ ret <32 x i8> %1
+}
+
;
; Zero Elts
;
>From 4c50705e1159aadc78676e6641362304a7df0725 Mon Sep 17 00:00:00 2001
From: Simon Pilgrim <llvm-dev at redking.me.uk>
Date: Thu, 1 Oct 2026 09:47:31 +0100
Subject: [PATCH 6/7] intrinsicPropagatesPoison - add smulh/umulh handling
---
llvm/lib/Analysis/ValueTracking.cpp | 2 ++
llvm/test/Transforms/InstCombine/smulh.ll | 8 ++++----
llvm/test/Transforms/InstCombine/umulh.ll | 8 ++++----
3 files changed, 10 insertions(+), 8 deletions(-)
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 650d07364bee1..8fc1414d5ba40 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -8466,6 +8466,8 @@ bool llvm::intrinsicPropagatesPoison(Intrinsic::ID IID) {
case Intrinsic::umax:
case Intrinsic::umin:
case Intrinsic::scmp:
+ case Intrinsic::smulh:
+ case Intrinsic::umulh:
case Intrinsic::is_fpclass:
case Intrinsic::ptrmask:
case Intrinsic::ucmp:
diff --git a/llvm/test/Transforms/InstCombine/smulh.ll b/llvm/test/Transforms/InstCombine/smulh.ll
index 69085237e321a..a04d9faa0ddd5 100644
--- a/llvm/test/Transforms/InstCombine/smulh.ll
+++ b/llvm/test/Transforms/InstCombine/smulh.ll
@@ -43,7 +43,7 @@ define <32 x i8> @undef_smulh_v32i8_commute(<32 x i8> %a0) {
define i32 @poison_smulh_i32(i32 %a0) {
; CHECK-LABEL: @poison_smulh_i32(
-; CHECK-NEXT: ret i32 0
+; CHECK-NEXT: ret i32 poison
;
%1 = call i32 @llvm.smulh.i32(i32 %a0, i32 poison)
ret i32 %1
@@ -51,7 +51,7 @@ define i32 @poison_smulh_i32(i32 %a0) {
define i32 @poison_smulh_i32_commute(i32 %a0) {
; CHECK-LABEL: @poison_smulh_i32_commute(
-; CHECK-NEXT: ret i32 0
+; CHECK-NEXT: ret i32 poison
;
%1 = call i32 @llvm.smulh.i32(i32 poison, i32 %a0)
ret i32 %1
@@ -59,7 +59,7 @@ define i32 @poison_smulh_i32_commute(i32 %a0) {
define <8 x i16> @poison_smulh_v8i16(<8 x i16> %a0) {
; CHECK-LABEL: @poison_smulh_v8i16(
-; CHECK-NEXT: ret <8 x i16> zeroinitializer
+; CHECK-NEXT: ret <8 x i16> poison
;
%1 = call <8 x i16> @llvm.smulh.v8i16(<8 x i16> %a0, <8 x i16> poison)
ret <8 x i16> %1
@@ -67,7 +67,7 @@ define <8 x i16> @poison_smulh_v8i16(<8 x i16> %a0) {
define <32 x i8> @poison_smulh_v32i8_commute(<32 x i8> %a0) {
; CHECK-LABEL: @poison_smulh_v32i8_commute(
-; CHECK-NEXT: ret <32 x i8> zeroinitializer
+; CHECK-NEXT: ret <32 x i8> poison
;
%1 = call <32 x i8> @llvm.smulh.v32i8(<32 x i8> poison, <32 x i8> %a0)
ret <32 x i8> %1
diff --git a/llvm/test/Transforms/InstCombine/umulh.ll b/llvm/test/Transforms/InstCombine/umulh.ll
index c198b20ce364c..b15ff83a043e4 100644
--- a/llvm/test/Transforms/InstCombine/umulh.ll
+++ b/llvm/test/Transforms/InstCombine/umulh.ll
@@ -43,7 +43,7 @@ define <32 x i8> @undef_umulh_v32i8_commute(<32 x i8> %a0) {
define i32 @poison_umulh_i32(i32 %a0) {
; CHECK-LABEL: @poison_umulh_i32(
-; CHECK-NEXT: ret i32 0
+; CHECK-NEXT: ret i32 poison
;
%1 = call i32 @llvm.umulh.i32(i32 %a0, i32 poison)
ret i32 %1
@@ -51,7 +51,7 @@ define i32 @poison_umulh_i32(i32 %a0) {
define i32 @poison_umulh_i32_commute(i32 %a0) {
; CHECK-LABEL: @poison_umulh_i32_commute(
-; CHECK-NEXT: ret i32 0
+; CHECK-NEXT: ret i32 poison
;
%1 = call i32 @llvm.umulh.i32(i32 poison, i32 %a0)
ret i32 %1
@@ -59,7 +59,7 @@ define i32 @poison_umulh_i32_commute(i32 %a0) {
define <8 x i16> @poison_umulh_v8i16(<8 x i16> %a0) {
; CHECK-LABEL: @poison_umulh_v8i16(
-; CHECK-NEXT: ret <8 x i16> zeroinitializer
+; CHECK-NEXT: ret <8 x i16> poison
;
%1 = call <8 x i16> @llvm.umulh.v8i16(<8 x i16> %a0, <8 x i16> poison)
ret <8 x i16> %1
@@ -67,7 +67,7 @@ define <8 x i16> @poison_umulh_v8i16(<8 x i16> %a0) {
define <32 x i8> @poison_umulh_v32i8_commute(<32 x i8> %a0) {
; CHECK-LABEL: @poison_umulh_v32i8_commute(
-; CHECK-NEXT: ret <32 x i8> zeroinitializer
+; CHECK-NEXT: ret <32 x i8> poison
;
%1 = call <32 x i8> @llvm.umulh.v32i8(<32 x i8> poison, <32 x i8> %a0)
ret <32 x i8> %1
>From 15bf392c971840715ae8d3d4799a0e99842a4d94 Mon Sep 17 00:00:00 2001
From: Simon Pilgrim <llvm-dev at redking.me.uk>
Date: Thu, 1 Oct 2026 09:50:17 +0100
Subject: [PATCH 7/7] Assume smulh constants has already canonicalized to the
RHS
---
llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp | 2 --
1 file changed, 2 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index cba3386dba8a7..21c6bfd6e2e2f 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -2902,8 +2902,6 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
unsigned BitWidth = II->getType()->getScalarSizeInBits();
// Multiply by one.
- if (match(Arg0, m_One()))
- return replaceInstUsesWith(CI, Builder.CreateAShr(Arg1, BitWidth - 1));
if (match(Arg1, m_One()))
return replaceInstUsesWith(CI, Builder.CreateAShr(Arg0, BitWidth - 1));
break;
More information about the llvm-commits
mailing list