[llvm] [InstCombine] Fold xor-lshr sign-mask idiom to ashr (PR #213954)

via llvm-commits llvm-commits at lists.llvm.org
Sun Sep 13 05:54:58 PDT 2026


https://github.com/GabrielKimm updated https://github.com/llvm/llvm-project/pull/213954

>From f8604bb73d029912e1cce6d5db2314c46f00e801 Mon Sep 17 00:00:00 2001
From: GabrielKim <0xGabriel.kim at gmail.com>
Date: Sun, 2 Aug 2026 21:19:00 +0900
Subject: [PATCH 1/2] [InstCombine] Add tests for xor-lshr sign-mask idiom

Add pre-commit coverage for the missed optimization in #204851, including commuted operands, exact shifts, unusual integer widths, vector poison, scalable vectors, and negative one-use/source/shift cases.
---
 .../InstCombine/binop-and-shifts.ll           | 199 ++++++++++++++++++
 1 file changed, 199 insertions(+)

diff --git a/llvm/test/Transforms/InstCombine/binop-and-shifts.ll b/llvm/test/Transforms/InstCombine/binop-and-shifts.ll
index 40275fd29fde1..bfae87ac78b99 100644
--- a/llvm/test/Transforms/InstCombine/binop-and-shifts.ll
+++ b/llvm/test/Transforms/InstCombine/binop-and-shifts.ll
@@ -1,6 +1,8 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
 
+declare void @use(i8)
+
 define i8 @shl_and_and(i8 %x, i8 %y) {
 ; CHECK-LABEL: @shl_and_and(
 ; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[Y:%.*]], [[X:%.*]]
@@ -951,6 +953,203 @@ define <4 x i8> @xor_ashr_not_vec_poison_2(<4 x i8> %x, <4 x i8> %y, <4 x i8> %s
   ret <4 x i8> %xor
 }
 
+define i8 @xor_lshr_signmask(i8 %x, i8 %shamt) {
+; CHECK-LABEL: @xor_lshr_signmask(
+; CHECK-NEXT:    [[SIGNMASK:%.*]] = ashr i8 [[X:%.*]], 7
+; CHECK-NEXT:    [[FLIPPED:%.*]] = xor i8 [[X]], [[SIGNMASK]]
+; CHECK-NEXT:    [[SHIFTED:%.*]] = lshr i8 [[FLIPPED]], [[SHAMT:%.*]]
+; CHECK-NEXT:    [[R:%.*]] = xor i8 [[SHIFTED]], [[SIGNMASK]]
+; CHECK-NEXT:    ret i8 [[R]]
+;
+  %signmask = ashr i8 %x, 7
+  %flipped = xor i8 %x, %signmask
+  %shifted = lshr i8 %flipped, %shamt
+  %r = xor i8 %shifted, %signmask
+  ret i8 %r
+}
+
+define i8 @xor_lshr_signmask_commuted(i8 %x, i8 %shamt) {
+; CHECK-LABEL: @xor_lshr_signmask_commuted(
+; CHECK-NEXT:    [[SIGNMASK:%.*]] = ashr i8 [[X:%.*]], 7
+; CHECK-NEXT:    [[FLIPPED:%.*]] = xor i8 [[SIGNMASK]], [[X]]
+; CHECK-NEXT:    [[SHIFTED:%.*]] = lshr i8 [[FLIPPED]], [[SHAMT:%.*]]
+; CHECK-NEXT:    [[R:%.*]] = xor i8 [[SIGNMASK]], [[SHIFTED]]
+; CHECK-NEXT:    ret i8 [[R]]
+;
+  %signmask = ashr i8 %x, 7
+  %flipped = xor i8 %signmask, %x
+  %shifted = lshr i8 %flipped, %shamt
+  %r = xor i8 %signmask, %shifted
+  ret i8 %r
+}
+
+define i8 @xor_lshr_signmask_exact(i8 %x, i8 %shamt) {
+; CHECK-LABEL: @xor_lshr_signmask_exact(
+; CHECK-NEXT:    [[SIGNMASK:%.*]] = ashr i8 [[X:%.*]], 7
+; CHECK-NEXT:    [[FLIPPED:%.*]] = xor i8 [[X]], [[SIGNMASK]]
+; CHECK-NEXT:    [[SHIFTED:%.*]] = lshr exact i8 [[FLIPPED]], [[SHAMT:%.*]]
+; CHECK-NEXT:    [[R:%.*]] = xor i8 [[SHIFTED]], [[SIGNMASK]]
+; CHECK-NEXT:    ret i8 [[R]]
+;
+  %signmask = ashr i8 %x, 7
+  %flipped = xor i8 %x, %signmask
+  %shifted = lshr exact i8 %flipped, %shamt
+  %r = xor i8 %shifted, %signmask
+  ret i8 %r
+}
+
+define i1 @xor_lshr_signmask_i1(i1 %x, i1 %shamt) {
+; CHECK-LABEL: @xor_lshr_signmask_i1(
+; CHECK-NEXT:    ret i1 [[X:%.*]]
+;
+  %signmask = ashr i1 %x, 0
+  %flipped = xor i1 %x, %signmask
+  %shifted = lshr i1 %flipped, %shamt
+  %r = xor i1 %shifted, %signmask
+  ret i1 %r
+}
+
+define i13 @xor_lshr_signmask_i13(i13 %x, i13 %shamt) {
+; CHECK-LABEL: @xor_lshr_signmask_i13(
+; CHECK-NEXT:    [[SIGNMASK:%.*]] = ashr i13 [[X:%.*]], 12
+; CHECK-NEXT:    [[FLIPPED:%.*]] = xor i13 [[X]], [[SIGNMASK]]
+; CHECK-NEXT:    [[SHIFTED:%.*]] = lshr i13 [[FLIPPED]], [[SHAMT:%.*]]
+; CHECK-NEXT:    [[R:%.*]] = xor i13 [[SHIFTED]], [[SIGNMASK]]
+; CHECK-NEXT:    ret i13 [[R]]
+;
+  %signmask = ashr i13 %x, 12
+  %flipped = xor i13 %x, %signmask
+  %shifted = lshr i13 %flipped, %shamt
+  %r = xor i13 %shifted, %signmask
+  ret i13 %r
+}
+
+define i8 @xor_lshr_signmask_signmask_exact(i8 %x, i8 %shamt) {
+; CHECK-LABEL: @xor_lshr_signmask_signmask_exact(
+; CHECK-NEXT:    [[SIGNMASK:%.*]] = ashr exact i8 [[X:%.*]], 7
+; CHECK-NEXT:    [[FLIPPED:%.*]] = xor i8 [[X]], [[SIGNMASK]]
+; CHECK-NEXT:    [[SHIFTED:%.*]] = lshr i8 [[FLIPPED]], [[SHAMT:%.*]]
+; CHECK-NEXT:    [[R:%.*]] = xor i8 [[SHIFTED]], [[SIGNMASK]]
+; CHECK-NEXT:    ret i8 [[R]]
+;
+  %signmask = ashr exact i8 %x, 7
+  %flipped = xor i8 %x, %signmask
+  %shifted = lshr i8 %flipped, %shamt
+  %r = xor i8 %shifted, %signmask
+  ret i8 %r
+}
+
+define { i8, i8 } @xor_lshr_signmask_inner_multiuse(i8 %x, i8 %shamt) {
+; CHECK-LABEL: @xor_lshr_signmask_inner_multiuse(
+; CHECK-NEXT:    [[SIGNMASK:%.*]] = ashr i8 [[X:%.*]], 7
+; CHECK-NEXT:    [[FLIPPED:%.*]] = xor i8 [[X]], [[SIGNMASK]]
+; CHECK-NEXT:    [[SHIFTED:%.*]] = lshr i8 [[FLIPPED]], [[SHAMT:%.*]]
+; CHECK-NEXT:    [[R:%.*]] = xor i8 [[SHIFTED]], [[SIGNMASK]]
+; CHECK-NEXT:    [[R0:%.*]] = insertvalue { i8, i8 } poison, i8 [[R]], 0
+; CHECK-NEXT:    [[R1:%.*]] = insertvalue { i8, i8 } [[R0]], i8 [[FLIPPED]], 1
+; CHECK-NEXT:    ret { i8, i8 } [[R1]]
+;
+  %signmask = ashr i8 %x, 7
+  %flipped = xor i8 %x, %signmask
+  %shifted = lshr i8 %flipped, %shamt
+  %r = xor i8 %shifted, %signmask
+  %r0 = insertvalue { i8, i8 } poison, i8 %r, 0
+  %r1 = insertvalue { i8, i8 } %r0, i8 %flipped, 1
+  ret { i8, i8 } %r1
+}
+
+define <4 x i8> @xor_lshr_signmask_vec_poison(<4 x i8> %x, <4 x i8> %shamt) {
+; CHECK-LABEL: @xor_lshr_signmask_vec_poison(
+; CHECK-NEXT:    [[SIGNMASK:%.*]] = ashr <4 x i8> [[X:%.*]], <i8 7, i8 poison, i8 7, i8 poison>
+; CHECK-NEXT:    [[FLIPPED:%.*]] = xor <4 x i8> [[X]], [[SIGNMASK]]
+; CHECK-NEXT:    [[SHIFTED:%.*]] = lshr <4 x i8> [[FLIPPED]], [[SHAMT:%.*]]
+; CHECK-NEXT:    [[R:%.*]] = xor <4 x i8> [[SHIFTED]], [[SIGNMASK]]
+; CHECK-NEXT:    ret <4 x i8> [[R]]
+;
+  %signmask = ashr <4 x i8> %x, <i8 7, i8 poison, i8 7, i8 poison>
+  %flipped = xor <4 x i8> %x, %signmask
+  %shifted = lshr <4 x i8> %flipped, %shamt
+  %r = xor <4 x i8> %shifted, %signmask
+  ret <4 x i8> %r
+}
+
+define <vscale x 4 x i8> @xor_lshr_signmask_scalable(<vscale x 4 x i8> %x, <vscale x 4 x i8> %shamt) {
+; CHECK-LABEL: @xor_lshr_signmask_scalable(
+; CHECK-NEXT:    [[SIGNMASK:%.*]] = ashr <vscale x 4 x i8> [[X:%.*]], splat (i8 7)
+; CHECK-NEXT:    [[FLIPPED:%.*]] = xor <vscale x 4 x i8> [[X]], [[SIGNMASK]]
+; CHECK-NEXT:    [[SHIFTED:%.*]] = lshr <vscale x 4 x i8> [[FLIPPED]], [[SHAMT:%.*]]
+; CHECK-NEXT:    [[R:%.*]] = xor <vscale x 4 x i8> [[SHIFTED]], [[SIGNMASK]]
+; CHECK-NEXT:    ret <vscale x 4 x i8> [[R]]
+;
+  %signmask = ashr <vscale x 4 x i8> %x, splat (i8 7)
+  %flipped = xor <vscale x 4 x i8> %x, %signmask
+  %shifted = lshr <vscale x 4 x i8> %flipped, %shamt
+  %r = xor <vscale x 4 x i8> %shifted, %signmask
+  ret <vscale x 4 x i8> %r
+}
+
+define i8 @xor_lshr_signmask_wrong_source(i8 %x, i8 %y, i8 %shamt) {
+; CHECK-LABEL: @xor_lshr_signmask_wrong_source(
+; CHECK-NEXT:    [[SIGNMASK:%.*]] = ashr i8 [[Y:%.*]], 7
+; CHECK-NEXT:    [[FLIPPED:%.*]] = xor i8 [[X:%.*]], [[SIGNMASK]]
+; CHECK-NEXT:    [[SHIFTED:%.*]] = lshr i8 [[FLIPPED]], [[SHAMT:%.*]]
+; CHECK-NEXT:    [[R:%.*]] = xor i8 [[SHIFTED]], [[SIGNMASK]]
+; CHECK-NEXT:    ret i8 [[R]]
+;
+  %signmask = ashr i8 %y, 7
+  %flipped = xor i8 %x, %signmask
+  %shifted = lshr i8 %flipped, %shamt
+  %r = xor i8 %shifted, %signmask
+  ret i8 %r
+}
+
+define i8 @xor_lshr_signmask_wrong_full_shift(i8 %x, i8 %shamt) {
+; CHECK-LABEL: @xor_lshr_signmask_wrong_full_shift(
+; CHECK-NEXT:    [[SIGNMASK:%.*]] = ashr i8 [[X:%.*]], 6
+; CHECK-NEXT:    [[FLIPPED:%.*]] = xor i8 [[X]], [[SIGNMASK]]
+; CHECK-NEXT:    [[SHIFTED:%.*]] = lshr i8 [[FLIPPED]], [[SHAMT:%.*]]
+; CHECK-NEXT:    [[R:%.*]] = xor i8 [[SHIFTED]], [[SIGNMASK]]
+; CHECK-NEXT:    ret i8 [[R]]
+;
+  %signmask = ashr i8 %x, 6
+  %flipped = xor i8 %x, %signmask
+  %shifted = lshr i8 %flipped, %shamt
+  %r = xor i8 %shifted, %signmask
+  ret i8 %r
+}
+
+define i8 @xor_lshr_signmask_lshr_multiuse(i8 %x, i8 %shamt) {
+; CHECK-LABEL: @xor_lshr_signmask_lshr_multiuse(
+; CHECK-NEXT:    [[SIGNMASK:%.*]] = ashr i8 [[X:%.*]], 7
+; CHECK-NEXT:    [[FLIPPED:%.*]] = xor i8 [[X]], [[SIGNMASK]]
+; CHECK-NEXT:    [[SHIFTED:%.*]] = lshr i8 [[FLIPPED]], [[SHAMT:%.*]]
+; CHECK-NEXT:    call void @use(i8 [[SHIFTED]])
+; CHECK-NEXT:    [[R:%.*]] = xor i8 [[SHIFTED]], [[SIGNMASK]]
+; CHECK-NEXT:    ret i8 [[R]]
+;
+  %signmask = ashr i8 %x, 7
+  %flipped = xor i8 %x, %signmask
+  %shifted = lshr i8 %flipped, %shamt
+  call void @use(i8 %shifted)
+  %r = xor i8 %shifted, %signmask
+  ret i8 %r
+}
+
+define <4 x i8> @xor_lshr_signmask_vec_nonsplat(<4 x i8> %x, <4 x i8> %shamt) {
+; CHECK-LABEL: @xor_lshr_signmask_vec_nonsplat(
+; CHECK-NEXT:    [[SIGNMASK:%.*]] = ashr <4 x i8> [[X:%.*]], <i8 7, i8 6, i8 7, i8 6>
+; CHECK-NEXT:    [[FLIPPED:%.*]] = xor <4 x i8> [[X]], [[SIGNMASK]]
+; CHECK-NEXT:    [[SHIFTED:%.*]] = lshr <4 x i8> [[FLIPPED]], [[SHAMT:%.*]]
+; CHECK-NEXT:    [[R:%.*]] = xor <4 x i8> [[SHIFTED]], [[SIGNMASK]]
+; CHECK-NEXT:    ret <4 x i8> [[R]]
+;
+  %signmask = ashr <4 x i8> %x, <i8 7, i8 6, i8 7, i8 6>
+  %flipped = xor <4 x i8> %x, %signmask
+  %shifted = lshr <4 x i8> %flipped, %shamt
+  %r = xor <4 x i8> %shifted, %signmask
+  ret <4 x i8> %r
+}
+
 ; Negative test: outer binop has multiple users
 
 define i8 @shl_add_add_multiuse_binop(i8 %x, i8 %y0, i8 %y1) {

>From 48b35560e49e6624d54b37ba79f3408925cfea15 Mon Sep 17 00:00:00 2001
From: GabrielKim <0xGabriel.kim at gmail.com>
Date: Sun, 2 Aug 2026 21:19:24 +0900
Subject: [PATCH 2/2] [InstCombine] Fold xor-lshr sign-mask idiom to ashr

Fold ((X ^ SignMask) lshr ShiftAmt) ^ SignMask to X ashr ShiftAmt when SignMask is X ashr (BitWidth - 1). Require the lshr to have one use so the fold does not increase instruction count, while still allowing the inner xor to remain live.

The replacement intentionally does not propagate exact flags. The matcher supports commuted xor operands and scalar, fixed-vector, and scalable-vector integer types.

Fixes #204851
---
 .../InstCombine/InstCombineAndOrXor.cpp       | 12 ++++++
 .../InstCombine/binop-and-shifts.ll           | 38 ++++---------------
 2 files changed, 20 insertions(+), 30 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index cd7fed74a4cf3..c121959ab0888 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -5433,6 +5433,18 @@ Instruction *InstCombinerImpl::visitXor(BinaryOperator &I) {
   if (Instruction *R = foldBinOpShiftWithShift(I))
     return R;
 
+  // ((X ^ SignMask) >>u ShiftAmt) ^ SignMask --> X >>s ShiftAmt
+  // where SignMask = X >>s (BitWidth - 1).
+  Value *Base, *SignMask, *ShiftAmt;
+  if (match(&I, m_c_Xor(m_Value(SignMask),
+                        m_OneUse(
+                            m_LShr(m_c_Xor(m_Deferred(SignMask), m_Value(Base)),
+                                   m_Value(ShiftAmt))))) &&
+      match(SignMask, m_AShr(m_Specific(Base),
+                             m_SpecificIntAllowPoison(
+                                 I.getType()->getScalarSizeInBits() - 1))))
+    return BinaryOperator::CreateAShr(Base, ShiftAmt);
+
   Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
   Value *X, *Y, *M;
 
diff --git a/llvm/test/Transforms/InstCombine/binop-and-shifts.ll b/llvm/test/Transforms/InstCombine/binop-and-shifts.ll
index bfae87ac78b99..8b6cf68249da6 100644
--- a/llvm/test/Transforms/InstCombine/binop-and-shifts.ll
+++ b/llvm/test/Transforms/InstCombine/binop-and-shifts.ll
@@ -955,10 +955,7 @@ define <4 x i8> @xor_ashr_not_vec_poison_2(<4 x i8> %x, <4 x i8> %y, <4 x i8> %s
 
 define i8 @xor_lshr_signmask(i8 %x, i8 %shamt) {
 ; CHECK-LABEL: @xor_lshr_signmask(
-; CHECK-NEXT:    [[SIGNMASK:%.*]] = ashr i8 [[X:%.*]], 7
-; CHECK-NEXT:    [[FLIPPED:%.*]] = xor i8 [[X]], [[SIGNMASK]]
-; CHECK-NEXT:    [[SHIFTED:%.*]] = lshr i8 [[FLIPPED]], [[SHAMT:%.*]]
-; CHECK-NEXT:    [[R:%.*]] = xor i8 [[SHIFTED]], [[SIGNMASK]]
+; CHECK-NEXT:    [[R:%.*]] = ashr i8 [[X:%.*]], [[SHAMT:%.*]]
 ; CHECK-NEXT:    ret i8 [[R]]
 ;
   %signmask = ashr i8 %x, 7
@@ -970,10 +967,7 @@ define i8 @xor_lshr_signmask(i8 %x, i8 %shamt) {
 
 define i8 @xor_lshr_signmask_commuted(i8 %x, i8 %shamt) {
 ; CHECK-LABEL: @xor_lshr_signmask_commuted(
-; CHECK-NEXT:    [[SIGNMASK:%.*]] = ashr i8 [[X:%.*]], 7
-; CHECK-NEXT:    [[FLIPPED:%.*]] = xor i8 [[SIGNMASK]], [[X]]
-; CHECK-NEXT:    [[SHIFTED:%.*]] = lshr i8 [[FLIPPED]], [[SHAMT:%.*]]
-; CHECK-NEXT:    [[R:%.*]] = xor i8 [[SIGNMASK]], [[SHIFTED]]
+; CHECK-NEXT:    [[R:%.*]] = ashr i8 [[X:%.*]], [[SHAMT:%.*]]
 ; CHECK-NEXT:    ret i8 [[R]]
 ;
   %signmask = ashr i8 %x, 7
@@ -985,10 +979,7 @@ define i8 @xor_lshr_signmask_commuted(i8 %x, i8 %shamt) {
 
 define i8 @xor_lshr_signmask_exact(i8 %x, i8 %shamt) {
 ; CHECK-LABEL: @xor_lshr_signmask_exact(
-; CHECK-NEXT:    [[SIGNMASK:%.*]] = ashr i8 [[X:%.*]], 7
-; CHECK-NEXT:    [[FLIPPED:%.*]] = xor i8 [[X]], [[SIGNMASK]]
-; CHECK-NEXT:    [[SHIFTED:%.*]] = lshr exact i8 [[FLIPPED]], [[SHAMT:%.*]]
-; CHECK-NEXT:    [[R:%.*]] = xor i8 [[SHIFTED]], [[SIGNMASK]]
+; CHECK-NEXT:    [[R:%.*]] = ashr i8 [[X:%.*]], [[SHAMT:%.*]]
 ; CHECK-NEXT:    ret i8 [[R]]
 ;
   %signmask = ashr i8 %x, 7
@@ -1011,10 +1002,7 @@ define i1 @xor_lshr_signmask_i1(i1 %x, i1 %shamt) {
 
 define i13 @xor_lshr_signmask_i13(i13 %x, i13 %shamt) {
 ; CHECK-LABEL: @xor_lshr_signmask_i13(
-; CHECK-NEXT:    [[SIGNMASK:%.*]] = ashr i13 [[X:%.*]], 12
-; CHECK-NEXT:    [[FLIPPED:%.*]] = xor i13 [[X]], [[SIGNMASK]]
-; CHECK-NEXT:    [[SHIFTED:%.*]] = lshr i13 [[FLIPPED]], [[SHAMT:%.*]]
-; CHECK-NEXT:    [[R:%.*]] = xor i13 [[SHIFTED]], [[SIGNMASK]]
+; CHECK-NEXT:    [[R:%.*]] = ashr i13 [[X:%.*]], [[SHAMT:%.*]]
 ; CHECK-NEXT:    ret i13 [[R]]
 ;
   %signmask = ashr i13 %x, 12
@@ -1026,10 +1014,7 @@ define i13 @xor_lshr_signmask_i13(i13 %x, i13 %shamt) {
 
 define i8 @xor_lshr_signmask_signmask_exact(i8 %x, i8 %shamt) {
 ; CHECK-LABEL: @xor_lshr_signmask_signmask_exact(
-; CHECK-NEXT:    [[SIGNMASK:%.*]] = ashr exact i8 [[X:%.*]], 7
-; CHECK-NEXT:    [[FLIPPED:%.*]] = xor i8 [[X]], [[SIGNMASK]]
-; CHECK-NEXT:    [[SHIFTED:%.*]] = lshr i8 [[FLIPPED]], [[SHAMT:%.*]]
-; CHECK-NEXT:    [[R:%.*]] = xor i8 [[SHIFTED]], [[SIGNMASK]]
+; CHECK-NEXT:    [[R:%.*]] = ashr i8 [[X:%.*]], [[SHAMT:%.*]]
 ; CHECK-NEXT:    ret i8 [[R]]
 ;
   %signmask = ashr exact i8 %x, 7
@@ -1043,8 +1028,7 @@ define { i8, i8 } @xor_lshr_signmask_inner_multiuse(i8 %x, i8 %shamt) {
 ; CHECK-LABEL: @xor_lshr_signmask_inner_multiuse(
 ; CHECK-NEXT:    [[SIGNMASK:%.*]] = ashr i8 [[X:%.*]], 7
 ; CHECK-NEXT:    [[FLIPPED:%.*]] = xor i8 [[X]], [[SIGNMASK]]
-; CHECK-NEXT:    [[SHIFTED:%.*]] = lshr i8 [[FLIPPED]], [[SHAMT:%.*]]
-; CHECK-NEXT:    [[R:%.*]] = xor i8 [[SHIFTED]], [[SIGNMASK]]
+; CHECK-NEXT:    [[R:%.*]] = ashr i8 [[X]], [[SHAMT:%.*]]
 ; CHECK-NEXT:    [[R0:%.*]] = insertvalue { i8, i8 } poison, i8 [[R]], 0
 ; CHECK-NEXT:    [[R1:%.*]] = insertvalue { i8, i8 } [[R0]], i8 [[FLIPPED]], 1
 ; CHECK-NEXT:    ret { i8, i8 } [[R1]]
@@ -1060,10 +1044,7 @@ define { i8, i8 } @xor_lshr_signmask_inner_multiuse(i8 %x, i8 %shamt) {
 
 define <4 x i8> @xor_lshr_signmask_vec_poison(<4 x i8> %x, <4 x i8> %shamt) {
 ; CHECK-LABEL: @xor_lshr_signmask_vec_poison(
-; CHECK-NEXT:    [[SIGNMASK:%.*]] = ashr <4 x i8> [[X:%.*]], <i8 7, i8 poison, i8 7, i8 poison>
-; CHECK-NEXT:    [[FLIPPED:%.*]] = xor <4 x i8> [[X]], [[SIGNMASK]]
-; CHECK-NEXT:    [[SHIFTED:%.*]] = lshr <4 x i8> [[FLIPPED]], [[SHAMT:%.*]]
-; CHECK-NEXT:    [[R:%.*]] = xor <4 x i8> [[SHIFTED]], [[SIGNMASK]]
+; CHECK-NEXT:    [[R:%.*]] = ashr <4 x i8> [[X:%.*]], [[SHAMT:%.*]]
 ; CHECK-NEXT:    ret <4 x i8> [[R]]
 ;
   %signmask = ashr <4 x i8> %x, <i8 7, i8 poison, i8 7, i8 poison>
@@ -1075,10 +1056,7 @@ define <4 x i8> @xor_lshr_signmask_vec_poison(<4 x i8> %x, <4 x i8> %shamt) {
 
 define <vscale x 4 x i8> @xor_lshr_signmask_scalable(<vscale x 4 x i8> %x, <vscale x 4 x i8> %shamt) {
 ; CHECK-LABEL: @xor_lshr_signmask_scalable(
-; CHECK-NEXT:    [[SIGNMASK:%.*]] = ashr <vscale x 4 x i8> [[X:%.*]], splat (i8 7)
-; CHECK-NEXT:    [[FLIPPED:%.*]] = xor <vscale x 4 x i8> [[X]], [[SIGNMASK]]
-; CHECK-NEXT:    [[SHIFTED:%.*]] = lshr <vscale x 4 x i8> [[FLIPPED]], [[SHAMT:%.*]]
-; CHECK-NEXT:    [[R:%.*]] = xor <vscale x 4 x i8> [[SHIFTED]], [[SIGNMASK]]
+; CHECK-NEXT:    [[R:%.*]] = ashr <vscale x 4 x i8> [[X:%.*]], [[SHAMT:%.*]]
 ; CHECK-NEXT:    ret <vscale x 4 x i8> [[R]]
 ;
   %signmask = ashr <vscale x 4 x i8> %x, splat (i8 7)



More information about the llvm-commits mailing list