From 9383a353d3a12282279fd7e68b2d15a80a45dd05 Mon Sep 17 00:00:00 2001 From: abhishek-kaushik22 Date: Thu, 6 Feb 2025 02:55:03 +0530 Subject: [PATCH 01/10] [ValueTracking] Improve `Bitcast` handling to match SDAG Closes #125228 --- llvm/lib/Analysis/ValueTracking.cpp | 31 ++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index a17417cb5189c..de0809fced8ab 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -1349,6 +1349,9 @@ static void computeKnownBitsFromOperator(const Operator *I, // Look through a cast from narrow vector elements to wider type. // Examples: v4i32 -> v2i64, v3i8 -> v24 unsigned SubBitWidth = SrcVecTy->getScalarSizeInBits(); + unsigned NumElts = DemandedElts.getBitWidth(); + unsigned SubScale = BitWidth / SubBitWidth; + bool isLE = Q.DL.isLittleEndian(); if (BitWidth % SubBitWidth == 0) { // Known bits are automatically intersected across demanded elements of a // vector. So for example, if a bit is computed as known zero, it must be @@ -1364,8 +1367,6 @@ static void computeKnownBitsFromOperator(const Operator *I, // // The known bits of each sub-element are then inserted into place // (dependent on endian) to form the full result of known bits. - unsigned NumElts = DemandedElts.getBitWidth(); - unsigned SubScale = BitWidth / SubBitWidth; APInt SubDemandedElts = APInt::getZero(NumElts * SubScale); for (unsigned i = 0; i != NumElts; ++i) { if (DemandedElts[i]) @@ -1374,12 +1375,32 @@ static void computeKnownBitsFromOperator(const Operator *I, KnownBits KnownSrc(SubBitWidth); for (unsigned i = 0; i != SubScale; ++i) { - computeKnownBits(I->getOperand(0), SubDemandedElts.shl(i), KnownSrc, Q, - Depth + 1); - unsigned ShiftElt = Q.DL.isLittleEndian() ? i : SubScale - 1 - i; + computeKnownBits(I->getOperand(0), SubDemandedElts.shl(i), KnownSrc, + Depth + 1, Q); + unsigned ShiftElt = isLE ? i : SubScale - 1 - i; Known.insertBits(KnownSrc, ShiftElt * SubBitWidth); } } + + if (SubBitWidth % BitWidth == 0) { + KnownBits KnownSrc(SubBitWidth); + APInt SubDemandedElts = + APIntOps::ScaleBitMask(DemandedElts, NumElts / SubScale); + computeKnownBits(I->getOperand(0), SubDemandedElts, KnownSrc, Depth + 1, + Q); + + Known.Zero.setAllBits(); + Known.One.setAllBits(); + for (unsigned i = 0; i != SubScale; ++i) { + if (DemandedElts[i]) { + unsigned Shifts = isLE ? i : NumElts - 1 - i; + unsigned Offset = (Shifts % SubScale) * BitWidth; + Known = Known.intersectWith(KnownSrc.extractBits(BitWidth, Offset)); + if (Known.isUnknown()) + break; + } + } + } break; } case Instruction::SExt: { From 34e0a817553b8a918de2f5928871916ee9542456 Mon Sep 17 00:00:00 2001 From: abhishek-kaushik22 Date: Thu, 6 Feb 2025 21:09:20 +0530 Subject: [PATCH 02/10] Minor change and tests added --- llvm/lib/Analysis/ValueTracking.cpp | 11 ++++++----- .../InstCombine/X86/x86-vector-shifts.ll | 14 ++++++++------ 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index de0809fced8ab..ba4dbf7f46d8f 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -1346,12 +1346,11 @@ static void computeKnownBitsFromOperator(const Operator *I, isa(I->getType())) break; + unsigned NumElts = DemandedElts.getBitWidth(); + bool IsLE = Q.DL.isLittleEndian(); // Look through a cast from narrow vector elements to wider type. // Examples: v4i32 -> v2i64, v3i8 -> v24 unsigned SubBitWidth = SrcVecTy->getScalarSizeInBits(); - unsigned NumElts = DemandedElts.getBitWidth(); - unsigned SubScale = BitWidth / SubBitWidth; - bool isLE = Q.DL.isLittleEndian(); if (BitWidth % SubBitWidth == 0) { // Known bits are automatically intersected across demanded elements of a // vector. So for example, if a bit is computed as known zero, it must be @@ -1367,6 +1366,7 @@ static void computeKnownBitsFromOperator(const Operator *I, // // The known bits of each sub-element are then inserted into place // (dependent on endian) to form the full result of known bits. + unsigned SubScale = BitWidth / SubBitWidth; APInt SubDemandedElts = APInt::getZero(NumElts * SubScale); for (unsigned i = 0; i != NumElts; ++i) { if (DemandedElts[i]) @@ -1377,12 +1377,13 @@ static void computeKnownBitsFromOperator(const Operator *I, for (unsigned i = 0; i != SubScale; ++i) { computeKnownBits(I->getOperand(0), SubDemandedElts.shl(i), KnownSrc, Depth + 1, Q); - unsigned ShiftElt = isLE ? i : SubScale - 1 - i; + unsigned ShiftElt = IsLE ? i : SubScale - 1 - i; Known.insertBits(KnownSrc, ShiftElt * SubBitWidth); } } if (SubBitWidth % BitWidth == 0) { + unsigned SubScale = SubBitWidth / BitWidth; KnownBits KnownSrc(SubBitWidth); APInt SubDemandedElts = APIntOps::ScaleBitMask(DemandedElts, NumElts / SubScale); @@ -1393,7 +1394,7 @@ static void computeKnownBitsFromOperator(const Operator *I, Known.One.setAllBits(); for (unsigned i = 0; i != SubScale; ++i) { if (DemandedElts[i]) { - unsigned Shifts = isLE ? i : NumElts - 1 - i; + unsigned Shifts = IsLE ? i : NumElts - 1 - i; unsigned Offset = (Shifts % SubScale) * BitWidth; Known = Known.intersectWith(KnownSrc.extractBits(BitWidth, Offset)); if (Known.isUnknown()) diff --git a/llvm/test/Transforms/InstCombine/X86/x86-vector-shifts.ll b/llvm/test/Transforms/InstCombine/X86/x86-vector-shifts.ll index db56080a3ea2b..9fb4bbc557f3c 100644 --- a/llvm/test/Transforms/InstCombine/X86/x86-vector-shifts.ll +++ b/llvm/test/Transforms/InstCombine/X86/x86-vector-shifts.ll @@ -3732,19 +3732,21 @@ define <4 x i64> @test_avx2_psrl_0() { ret <4 x i64> %16 } -; FIXME: Failure to peek through bitcasts to ensure psllq shift amount is within bounds. -define <2 x i64> @PR125228(<2 x i64> %v, <2 x i64> %s) { -; CHECK-LABEL: @PR125228( +define <2 x i64> @pr125228(<2 x i64> %v, <2 x i64> %s) { +; CHECK-LABEL: @pr125228( +; CHECK-NEXT: entry: ; CHECK-NEXT: [[MASK:%.*]] = and <2 x i64> [[S:%.*]], splat (i64 63) -; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <2 x i64> [[MASK]], <2 x i64> poison, <2 x i32> zeroinitializer -; CHECK-NEXT: [[SLL0:%.*]] = shl <2 x i64> [[V:%.*]], [[TMP1]] +; CHECK-NEXT: [[TMP0:%.*]] = shufflevector <2 x i64> [[MASK]], <2 x i64> poison, <2 x i32> zeroinitializer +; CHECK-NEXT: [[SLL0:%.*]] = shl <2 x i64> [[V:%.*]], [[TMP0]] ; CHECK-NEXT: [[CAST:%.*]] = bitcast <2 x i64> [[MASK]] to <16 x i8> ; CHECK-NEXT: [[PSRLDQ:%.*]] = shufflevector <16 x i8> [[CAST]], <16 x i8> poison, <16 x i32> ; CHECK-NEXT: [[CAST3:%.*]] = bitcast <16 x i8> [[PSRLDQ]] to <2 x i64> -; CHECK-NEXT: [[SLL1:%.*]] = call <2 x i64> @llvm.x86.sse2.psll.q(<2 x i64> [[V]], <2 x i64> [[CAST3]]) +; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <2 x i64> [[CAST3]], <2 x i64> poison, <2 x i32> zeroinitializer +; CHECK-NEXT: [[SLL1:%.*]] = shl <2 x i64> [[V]], [[TMP1]] ; CHECK-NEXT: [[SHUFP_UNCASTED:%.*]] = shufflevector <2 x i64> [[SLL0]], <2 x i64> [[SLL1]], <2 x i32> ; CHECK-NEXT: ret <2 x i64> [[SHUFP_UNCASTED]] ; +entry: %mask = and <2 x i64> %s, splat (i64 63) %sll0 = call <2 x i64> @llvm.x86.sse2.psll.q(<2 x i64> %v, <2 x i64> %mask) %cast = bitcast <2 x i64> %mask to <16 x i8> From 60b5456a8cf720c2939ac788b9b0c0a49f84207b Mon Sep 17 00:00:00 2001 From: abhishek-kaushik22 Date: Thu, 6 Feb 2025 21:22:09 +0530 Subject: [PATCH 03/10] Add comment --- llvm/lib/Analysis/ValueTracking.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index ba4dbf7f46d8f..57780cbeeae07 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -1381,7 +1381,8 @@ static void computeKnownBitsFromOperator(const Operator *I, Known.insertBits(KnownSrc, ShiftElt * SubBitWidth); } } - + // Look through a cast from wider vector elements to narrow type. + // Examples: v2i64 -> v4i32 if (SubBitWidth % BitWidth == 0) { unsigned SubScale = SubBitWidth / BitWidth; KnownBits KnownSrc(SubBitWidth); From a8393f7ed9ceae28c5a7c40083b3215596062f72 Mon Sep 17 00:00:00 2001 From: abhishek-kaushik22 Date: Sat, 22 Feb 2025 23:48:18 +0530 Subject: [PATCH 04/10] Update x86-vector-shifts.ll --- .../InstCombine/X86/x86-vector-shifts.ll | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/llvm/test/Transforms/InstCombine/X86/x86-vector-shifts.ll b/llvm/test/Transforms/InstCombine/X86/x86-vector-shifts.ll index 9fb4bbc557f3c..cc252ae53803b 100644 --- a/llvm/test/Transforms/InstCombine/X86/x86-vector-shifts.ll +++ b/llvm/test/Transforms/InstCombine/X86/x86-vector-shifts.ll @@ -3732,21 +3732,19 @@ define <4 x i64> @test_avx2_psrl_0() { ret <4 x i64> %16 } -define <2 x i64> @pr125228(<2 x i64> %v, <2 x i64> %s) { -; CHECK-LABEL: @pr125228( -; CHECK-NEXT: entry: +define <2 x i64> @PR125228(<2 x i64> %v, <2 x i64> %s) { +; CHECK-LABEL: @PR125228( ; CHECK-NEXT: [[MASK:%.*]] = and <2 x i64> [[S:%.*]], splat (i64 63) -; CHECK-NEXT: [[TMP0:%.*]] = shufflevector <2 x i64> [[MASK]], <2 x i64> poison, <2 x i32> zeroinitializer -; CHECK-NEXT: [[SLL0:%.*]] = shl <2 x i64> [[V:%.*]], [[TMP0]] +; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <2 x i64> [[MASK]], <2 x i64> poison, <2 x i32> zeroinitializer +; CHECK-NEXT: [[SLL0:%.*]] = shl <2 x i64> [[V:%.*]], [[TMP1]] ; CHECK-NEXT: [[CAST:%.*]] = bitcast <2 x i64> [[MASK]] to <16 x i8> ; CHECK-NEXT: [[PSRLDQ:%.*]] = shufflevector <16 x i8> [[CAST]], <16 x i8> poison, <16 x i32> ; CHECK-NEXT: [[CAST3:%.*]] = bitcast <16 x i8> [[PSRLDQ]] to <2 x i64> -; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <2 x i64> [[CAST3]], <2 x i64> poison, <2 x i32> zeroinitializer -; CHECK-NEXT: [[SLL1:%.*]] = shl <2 x i64> [[V]], [[TMP1]] +; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <2 x i64> [[CAST3]], <2 x i64> poison, <2 x i32> zeroinitializer +; CHECK-NEXT: [[SLL1:%.*]] = shl <2 x i64> [[V]], [[TMP2]] ; CHECK-NEXT: [[SHUFP_UNCASTED:%.*]] = shufflevector <2 x i64> [[SLL0]], <2 x i64> [[SLL1]], <2 x i32> ; CHECK-NEXT: ret <2 x i64> [[SHUFP_UNCASTED]] ; -entry: %mask = and <2 x i64> %s, splat (i64 63) %sll0 = call <2 x i64> @llvm.x86.sse2.psll.q(<2 x i64> %v, <2 x i64> %mask) %cast = bitcast <2 x i64> %mask to <16 x i8> From 40a1864453ed287bb98a87f13e23e3e3c58f2e7a Mon Sep 17 00:00:00 2001 From: Abhishek Kaushik Date: Thu, 5 Jun 2025 13:55:22 +0530 Subject: [PATCH 05/10] Add tests --- llvm/test/Transforms/InstCombine/pr125228.ll | 242 +++++++++++++++++++ 1 file changed, 242 insertions(+) create mode 100644 llvm/test/Transforms/InstCombine/pr125228.ll diff --git a/llvm/test/Transforms/InstCombine/pr125228.ll b/llvm/test/Transforms/InstCombine/pr125228.ll new file mode 100644 index 0000000000000..496721f46ff3e --- /dev/null +++ b/llvm/test/Transforms/InstCombine/pr125228.ll @@ -0,0 +1,242 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 +; RUN: opt < %s -passes=instcombine -S | FileCheck %s + +define <16 x i8> @wombat(<16 x i8> %arg) { +; CHECK-LABEL: define <16 x i8> @wombat( +; CHECK-SAME: <16 x i8> [[ARG:%.*]]) { +; CHECK-NEXT: [[BITCAST:%.*]] = bitcast <16 x i8> [[ARG]] to <8 x i16> +; CHECK-NEXT: [[LSHR:%.*]] = lshr <8 x i16> [[BITCAST]], splat (i16 4) +; CHECK-NEXT: [[BITCAST1:%.*]] = bitcast <8 x i16> [[LSHR]] to <16 x i8> +; CHECK-NEXT: [[AND:%.*]] = and <16 x i8> [[BITCAST1]], splat (i8 3) +; CHECK-NEXT: [[SHL:%.*]] = shl <8 x i16> [[BITCAST]], splat (i16 4) +; CHECK-NEXT: [[BITCAST2:%.*]] = bitcast <8 x i16> [[SHL]] to <16 x i8> +; CHECK-NEXT: [[AND3:%.*]] = and <16 x i8> [[BITCAST2]], splat (i8 48) +; CHECK-NEXT: [[OR:%.*]] = or disjoint <16 x i8> [[AND]], [[AND3]] +; CHECK-NEXT: [[BITCAST4:%.*]] = bitcast <16 x i8> [[OR]] to <8 x i16> +; CHECK-NEXT: [[SHL5:%.*]] = shl nuw <8 x i16> [[BITCAST4]], splat (i16 2) +; CHECK-NEXT: [[BITCAST6:%.*]] = bitcast <8 x i16> [[SHL5]] to <16 x i8> +; CHECK-NEXT: ret <16 x i8> [[BITCAST6]] +; + %bitcast = bitcast <16 x i8> %arg to <8 x i16> + %lshr = lshr <8 x i16> %bitcast, splat (i16 4) + %bitcast1 = bitcast <8 x i16> %lshr to <16 x i8> + %and = and <16 x i8> %bitcast1, splat (i8 3) + %shl = shl <8 x i16> %bitcast, splat (i16 4) + %bitcast2 = bitcast <8 x i16> %shl to <16 x i8> + %and3 = and <16 x i8> %bitcast2, splat (i8 48) + %or = or disjoint <16 x i8> %and, %and3 + %bitcast4 = bitcast <16 x i8> %or to <8 x i16> + %shl5 = shl nuw <8 x i16> %bitcast4, splat (i16 2) + %bitcast6 = bitcast <8 x i16> %shl5 to <16 x i8> + %and7 = and <16 x i8> %bitcast6, splat (i8 -4) + ret <16 x i8> %and7 +} + +define <16 x i8> @snork(<8 x i16> %arg) { +; CHECK-LABEL: define <16 x i8> @snork( +; CHECK-SAME: <8 x i16> [[ARG:%.*]]) { +; CHECK-NEXT: [[BITCAST:%.*]] = bitcast <8 x i16> [[ARG]] to <16 x i8> +; CHECK-NEXT: [[SHUFFLEVECTOR:%.*]] = shufflevector <16 x i8> [[BITCAST]], <16 x i8> poison, <16 x i32> +; CHECK-NEXT: [[BITCAST1:%.*]] = bitcast <16 x i8> [[SHUFFLEVECTOR]] to <8 x i16> +; CHECK-NEXT: [[LSHR:%.*]] = lshr <8 x i16> [[BITCAST1]], splat (i16 4) +; CHECK-NEXT: [[BITCAST2:%.*]] = bitcast <8 x i16> [[LSHR]] to <16 x i8> +; CHECK-NEXT: [[AND:%.*]] = and <16 x i8> [[BITCAST2]], splat (i8 3) +; CHECK-NEXT: [[SHL:%.*]] = shl <8 x i16> [[BITCAST1]], splat (i16 4) +; CHECK-NEXT: [[BITCAST3:%.*]] = bitcast <8 x i16> [[SHL]] to <16 x i8> +; CHECK-NEXT: [[AND4:%.*]] = and <16 x i8> [[BITCAST3]], splat (i8 48) +; CHECK-NEXT: [[OR:%.*]] = or disjoint <16 x i8> [[AND]], [[AND4]] +; CHECK-NEXT: [[BITCAST5:%.*]] = bitcast <16 x i8> [[OR]] to <8 x i16> +; CHECK-NEXT: [[SHL6:%.*]] = shl nuw <8 x i16> [[BITCAST5]], splat (i16 2) +; CHECK-NEXT: [[BITCAST7:%.*]] = bitcast <8 x i16> [[SHL6]] to <16 x i8> +; CHECK-NEXT: ret <16 x i8> [[BITCAST7]] +; + %bitcast = bitcast <8 x i16> %arg to <16 x i8> + %shufflevector = shufflevector <16 x i8> %bitcast, <16 x i8> poison, <16 x i32> + %bitcast1 = bitcast <16 x i8> %shufflevector to <8 x i16> + %lshr = lshr <8 x i16> %bitcast1, splat (i16 4) + %bitcast2 = bitcast <8 x i16> %lshr to <16 x i8> + %and = and <16 x i8> %bitcast2, splat (i8 3) + %shl = shl <8 x i16> %bitcast1, splat (i16 4) + %bitcast3 = bitcast <8 x i16> %shl to <16 x i8> + %and4 = and <16 x i8> %bitcast3, splat (i8 48) + %or = or disjoint <16 x i8> %and, %and4 + %bitcast5 = bitcast <16 x i8> %or to <8 x i16> + %shl6 = shl nuw <8 x i16> %bitcast5, splat (i16 2) + %bitcast7 = bitcast <8 x i16> %shl6 to <16 x i8> + %and8 = and <16 x i8> %bitcast7, splat (i8 -4) + ret <16 x i8> %and8 +} + +define <16 x i8> @wobble(<8 x i16> %arg) { +; CHECK-LABEL: define <16 x i8> @wobble( +; CHECK-SAME: <8 x i16> [[ARG:%.*]]) { +; CHECK-NEXT: [[BITCAST:%.*]] = bitcast <8 x i16> [[ARG]] to <16 x i8> +; CHECK-NEXT: [[AND:%.*]] = and <16 x i8> [[BITCAST]], splat (i8 15) +; CHECK-NEXT: [[SHUFFLEVECTOR:%.*]] = shufflevector <16 x i8> [[AND]], <16 x i8> poison, <16 x i32> +; CHECK-NEXT: [[BITCAST1:%.*]] = bitcast <16 x i8> [[SHUFFLEVECTOR]] to <8 x i16> +; CHECK-NEXT: [[SHL:%.*]] = shl nuw <8 x i16> [[BITCAST1]], splat (i16 4) +; CHECK-NEXT: [[BITCAST2:%.*]] = bitcast <8 x i16> [[SHL]] to <16 x i8> +; CHECK-NEXT: ret <16 x i8> [[BITCAST2]] +; + %bitcast = bitcast <8 x i16> %arg to <16 x i8> + %and = and <16 x i8> %bitcast, splat (i8 15) + %shufflevector = shufflevector <16 x i8> %and, <16 x i8> poison, <16 x i32> + %bitcast1 = bitcast <16 x i8> %shufflevector to <8 x i16> + %shl = shl nuw <8 x i16> %bitcast1, splat (i16 4) + %bitcast2 = bitcast <8 x i16> %shl to <16 x i8> + %and3 = and <16 x i8> %bitcast2, splat (i8 -16) + ret <16 x i8> %and3 +} + +define <16 x i8> @wobble.1(<8 x i16> %arg) { +; CHECK-LABEL: define <16 x i8> @wobble.1( +; CHECK-SAME: <8 x i16> [[ARG:%.*]]) { +; CHECK-NEXT: [[BITCAST:%.*]] = bitcast <8 x i16> [[ARG]] to <16 x i8> +; CHECK-NEXT: [[AND:%.*]] = and <16 x i8> [[BITCAST]], splat (i8 15) +; CHECK-NEXT: [[SHUFFLEVECTOR:%.*]] = shufflevector <16 x i8> [[AND]], <16 x i8> poison, <16 x i32> +; CHECK-NEXT: [[BITCAST1:%.*]] = bitcast <16 x i8> [[SHUFFLEVECTOR]] to <8 x i16> +; CHECK-NEXT: [[SHL:%.*]] = shl nuw <8 x i16> [[BITCAST1]], splat (i16 4) +; CHECK-NEXT: [[BITCAST2:%.*]] = bitcast <8 x i16> [[SHL]] to <16 x i8> +; CHECK-NEXT: ret <16 x i8> [[BITCAST2]] +; + %bitcast = bitcast <8 x i16> %arg to <16 x i8> + %and = and <16 x i8> %bitcast, splat (i8 15) + %shufflevector = shufflevector <16 x i8> %and, <16 x i8> poison, <16 x i32> + %bitcast1 = bitcast <16 x i8> %shufflevector to <8 x i16> + %shl = shl nuw <8 x i16> %bitcast1, splat (i16 4) + %bitcast2 = bitcast <8 x i16> %shl to <16 x i8> + %and3 = and <16 x i8> %bitcast2, splat (i8 -16) + ret <16 x i8> %and3 +} + +define <16 x i8> @pluto(<16 x i8> %arg) { +; CHECK-LABEL: define <16 x i8> @pluto( +; CHECK-SAME: <16 x i8> [[ARG:%.*]]) { +; CHECK-NEXT: [[SHUFFLEVECTOR:%.*]] = shufflevector <16 x i8> [[ARG]], <16 x i8> , <16 x i32> +; CHECK-NEXT: [[BITCAST:%.*]] = bitcast <16 x i8> [[SHUFFLEVECTOR]] to <8 x i16> +; CHECK-NEXT: [[MUL:%.*]] = mul nuw <8 x i16> [[BITCAST]], +; CHECK-NEXT: [[LSHR:%.*]] = lshr <8 x i16> [[MUL]], splat (i16 15) +; CHECK-NEXT: [[BITCAST1:%.*]] = bitcast <8 x i16> [[LSHR]] to <16 x i8> +; CHECK-NEXT: ret <16 x i8> [[BITCAST1]] +; + %shufflevector = shufflevector <16 x i8> %arg, <16 x i8> , <16 x i32> + %bitcast = bitcast <16 x i8> %shufflevector to <8 x i16> + %mul = mul nuw <8 x i16> %bitcast, + %lshr = lshr <8 x i16> %mul, splat (i16 15) + %bitcast1 = bitcast <8 x i16> %lshr to <16 x i8> + %and = and <16 x i8> %bitcast1, splat (i8 1) + ret <16 x i8> %and +} + +define <16 x i8> @wibble(<8 x i16> %arg) { +; CHECK-LABEL: define <16 x i8> @wibble( +; CHECK-SAME: <8 x i16> [[ARG:%.*]]) { +; CHECK-NEXT: [[BITCAST:%.*]] = bitcast <8 x i16> [[ARG]] to <16 x i8> +; CHECK-NEXT: [[SHUFFLEVECTOR:%.*]] = shufflevector <16 x i8> [[BITCAST]], <16 x i8> poison, <16 x i32> +; CHECK-NEXT: [[BITCAST1:%.*]] = bitcast <16 x i8> [[SHUFFLEVECTOR]] to <8 x i16> +; CHECK-NEXT: [[LSHR:%.*]] = lshr <8 x i16> [[BITCAST1]], splat (i16 4) +; CHECK-NEXT: [[BITCAST2:%.*]] = bitcast <8 x i16> [[LSHR]] to <16 x i8> +; CHECK-NEXT: [[AND:%.*]] = and <16 x i8> [[BITCAST2]], splat (i8 3) +; CHECK-NEXT: [[SHL:%.*]] = shl <8 x i16> [[BITCAST1]], splat (i16 4) +; CHECK-NEXT: [[BITCAST3:%.*]] = bitcast <8 x i16> [[SHL]] to <16 x i8> +; CHECK-NEXT: [[AND4:%.*]] = and <16 x i8> [[BITCAST3]], splat (i8 48) +; CHECK-NEXT: [[OR:%.*]] = or disjoint <16 x i8> [[AND]], [[AND4]] +; CHECK-NEXT: [[BITCAST5:%.*]] = bitcast <16 x i8> [[OR]] to <8 x i16> +; CHECK-NEXT: [[SHL6:%.*]] = shl nuw <8 x i16> [[BITCAST5]], splat (i16 2) +; CHECK-NEXT: [[BITCAST7:%.*]] = bitcast <8 x i16> [[SHL6]] to <16 x i8> +; CHECK-NEXT: ret <16 x i8> [[BITCAST7]] +; + %bitcast = bitcast <8 x i16> %arg to <16 x i8> + %shufflevector = shufflevector <16 x i8> %bitcast, <16 x i8> poison, <16 x i32> + %bitcast1 = bitcast <16 x i8> %shufflevector to <8 x i16> + %lshr = lshr <8 x i16> %bitcast1, splat (i16 4) + %bitcast2 = bitcast <8 x i16> %lshr to <16 x i8> + %and = and <16 x i8> %bitcast2, splat (i8 3) + %shl = shl <8 x i16> %bitcast1, splat (i16 4) + %bitcast3 = bitcast <8 x i16> %shl to <16 x i8> + %and4 = and <16 x i8> %bitcast3, splat (i8 48) + %or = or disjoint <16 x i8> %and, %and4 + %bitcast5 = bitcast <16 x i8> %or to <8 x i16> + %shl6 = shl nuw <8 x i16> %bitcast5, splat (i16 2) + %bitcast7 = bitcast <8 x i16> %shl6 to <16 x i8> + %and8 = and <16 x i8> %bitcast7, splat (i8 -4) + ret <16 x i8> %and8 +} + +define <16 x i8> @hoge(<4 x i32> %arg) { +; CHECK-LABEL: define <16 x i8> @hoge( +; CHECK-SAME: <4 x i32> [[ARG:%.*]]) { +; CHECK-NEXT: [[BITCAST:%.*]] = bitcast <4 x i32> [[ARG]] to <16 x i8> +; CHECK-NEXT: [[SHUFFLEVECTOR:%.*]] = shufflevector <16 x i8> [[BITCAST]], <16 x i8> poison, <16 x i32> +; CHECK-NEXT: [[BITCAST1:%.*]] = bitcast <16 x i8> [[SHUFFLEVECTOR]] to <8 x i16> +; CHECK-NEXT: [[SHL:%.*]] = shl <8 x i16> [[BITCAST1]], splat (i16 4) +; CHECK-NEXT: [[BITCAST2:%.*]] = bitcast <8 x i16> [[SHL]] to <16 x i8> +; CHECK-NEXT: [[AND:%.*]] = and <16 x i8> [[BITCAST2]], splat (i8 48) +; CHECK-NEXT: [[LSHR:%.*]] = lshr <8 x i16> [[BITCAST1]], splat (i16 4) +; CHECK-NEXT: [[BITCAST3:%.*]] = bitcast <8 x i16> [[LSHR]] to <16 x i8> +; CHECK-NEXT: [[AND4:%.*]] = and <16 x i8> [[BITCAST3]], splat (i8 3) +; CHECK-NEXT: [[OR:%.*]] = or disjoint <16 x i8> [[AND4]], [[AND]] +; CHECK-NEXT: [[BITCAST5:%.*]] = bitcast <16 x i8> [[OR]] to <8 x i16> +; CHECK-NEXT: [[SHL6:%.*]] = shl nuw <8 x i16> [[BITCAST5]], splat (i16 2) +; CHECK-NEXT: [[BITCAST7:%.*]] = bitcast <8 x i16> [[SHL6]] to <16 x i8> +; CHECK-NEXT: ret <16 x i8> [[BITCAST7]] +; + %bitcast = bitcast <4 x i32> %arg to <16 x i8> + %shufflevector = shufflevector <16 x i8> %bitcast, <16 x i8> poison, <16 x i32> + %bitcast1 = bitcast <16 x i8> %shufflevector to <8 x i16> + %shl = shl <8 x i16> %bitcast1, splat (i16 4) + %bitcast2 = bitcast <8 x i16> %shl to <16 x i8> + %and = and <16 x i8> %bitcast2, splat (i8 48) + %lshr = lshr <8 x i16> %bitcast1, splat (i16 4) + %bitcast3 = bitcast <8 x i16> %lshr to <16 x i8> + %and4 = and <16 x i8> %bitcast3, splat (i8 3) + %or = or disjoint <16 x i8> %and4, %and + %bitcast5 = bitcast <16 x i8> %or to <8 x i16> + %shl6 = shl nuw <8 x i16> %bitcast5, splat (i16 2) + %bitcast7 = bitcast <8 x i16> %shl6 to <16 x i8> + %and8 = and <16 x i8> %bitcast7, splat (i8 -4) + ret <16 x i8> %and8 +} + +define { i32, i1 } @wombat.2(i32 %arg, i32 %arg1, i32 %arg2, i32 %arg3) { +; CHECK-LABEL: define { i32, i1 } @wombat.2( +; CHECK-SAME: i32 [[ARG:%.*]], i32 [[ARG1:%.*]], i32 [[ARG2:%.*]], i32 [[ARG3:%.*]]) { +; CHECK-NEXT: [[INSERTELEMENT:%.*]] = insertelement <4 x i32> poison, i32 [[ARG2]], i64 0 +; CHECK-NEXT: [[INSERTELEMENT4:%.*]] = insertelement <4 x i32> [[INSERTELEMENT]], i32 [[ARG3]], i64 1 +; CHECK-NEXT: [[BITCAST:%.*]] = bitcast <4 x i32> [[INSERTELEMENT4]] to <2 x i64> +; CHECK-NEXT: [[CALL:%.*]] = tail call range(i64 0, 65) <2 x i64> @llvm.ctpop.v2i64(<2 x i64> [[BITCAST]]) +; CHECK-NEXT: [[BITCAST5:%.*]] = bitcast <2 x i64> [[CALL]] to <4 x i32> +; CHECK-NEXT: [[EXTRACTELEMENT:%.*]] = extractelement <4 x i32> [[BITCAST5]], i64 0 +; CHECK-NEXT: [[INSERTELEMENT6:%.*]] = insertelement <4 x i32> poison, i32 [[ARG]], i64 0 +; CHECK-NEXT: [[INSERTELEMENT7:%.*]] = insertelement <4 x i32> [[INSERTELEMENT6]], i32 [[ARG1]], i64 1 +; CHECK-NEXT: [[BITCAST8:%.*]] = bitcast <4 x i32> [[INSERTELEMENT7]] to <2 x i64> +; CHECK-NEXT: [[CALL9:%.*]] = tail call range(i64 0, 65) <2 x i64> @llvm.ctpop.v2i64(<2 x i64> [[BITCAST8]]) +; CHECK-NEXT: [[BITCAST10:%.*]] = bitcast <2 x i64> [[CALL9]] to <4 x i32> +; CHECK-NEXT: [[EXTRACTELEMENT11:%.*]] = extractelement <4 x i32> [[BITCAST10]], i64 0 +; CHECK-NEXT: [[CALL12:%.*]] = add nuw nsw i32 [[EXTRACTELEMENT]], [[EXTRACTELEMENT11]] +; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { i32, i1 } { i32 poison, i1 false }, i32 [[CALL12]], 0 +; CHECK-NEXT: ret { i32, i1 } [[TMP1]] +; + %insertelement = insertelement <4 x i32> poison, i32 %arg2, i64 0 + %insertelement4 = insertelement <4 x i32> %insertelement, i32 %arg3, i64 1 + %bitcast = bitcast <4 x i32> %insertelement4 to <2 x i64> + %call = tail call <2 x i64> @llvm.ctpop.v2i64(<2 x i64> %bitcast) + %bitcast5 = bitcast <2 x i64> %call to <4 x i32> + %extractelement = extractelement <4 x i32> %bitcast5, i64 0 + %insertelement6 = insertelement <4 x i32> poison, i32 %arg, i64 0 + %insertelement7 = insertelement <4 x i32> %insertelement6, i32 %arg1, i64 1 + %bitcast8 = bitcast <4 x i32> %insertelement7 to <2 x i64> + %call9 = tail call <2 x i64> @llvm.ctpop.v2i64(<2 x i64> %bitcast8) + %bitcast10 = bitcast <2 x i64> %call9 to <4 x i32> + %extractelement11 = extractelement <4 x i32> %bitcast10, i64 0 + %call12 = tail call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %extractelement, i32 %extractelement11) + ret { i32, i1 } %call12 +} + +; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none) +declare <2 x i64> @llvm.ctpop.v2i64(<2 x i64>) #0 + +; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none) +declare { i32, i1 } @llvm.uadd.with.overflow.i32(i32, i32) #0 + +attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } From 0bdef185e47276f85561568b8c038b4e2cebea13 Mon Sep 17 00:00:00 2001 From: Abhishek Kaushik Date: Fri, 13 Jun 2025 16:26:05 +0530 Subject: [PATCH 06/10] Update tests --- llvm/test/Transforms/InstCombine/pr125228.ll | 87 ++++++++++++++++---- 1 file changed, 69 insertions(+), 18 deletions(-) diff --git a/llvm/test/Transforms/InstCombine/pr125228.ll b/llvm/test/Transforms/InstCombine/pr125228.ll index 496721f46ff3e..5b1b6c29c0201 100644 --- a/llvm/test/Transforms/InstCombine/pr125228.ll +++ b/llvm/test/Transforms/InstCombine/pr125228.ll @@ -1,8 +1,8 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s -define <16 x i8> @wombat(<16 x i8> %arg) { -; CHECK-LABEL: define <16 x i8> @wombat( +define <16 x i8> @knownbits_bitcast_masked_shift(<16 x i8> %arg) { +; CHECK-LABEL: define <16 x i8> @knownbits_bitcast_masked_shift( ; CHECK-SAME: <16 x i8> [[ARG:%.*]]) { ; CHECK-NEXT: [[BITCAST:%.*]] = bitcast <16 x i8> [[ARG]] to <8 x i16> ; CHECK-NEXT: [[LSHR:%.*]] = lshr <8 x i16> [[BITCAST]], splat (i16 4) @@ -17,6 +17,7 @@ define <16 x i8> @wombat(<16 x i8> %arg) { ; CHECK-NEXT: [[BITCAST6:%.*]] = bitcast <8 x i16> [[SHL5]] to <16 x i8> ; CHECK-NEXT: ret <16 x i8> [[BITCAST6]] ; + %bitcast = bitcast <16 x i8> %arg to <8 x i16> %lshr = lshr <8 x i16> %bitcast, splat (i16 4) %bitcast1 = bitcast <8 x i16> %lshr to <16 x i8> @@ -32,8 +33,8 @@ define <16 x i8> @wombat(<16 x i8> %arg) { ret <16 x i8> %and7 } -define <16 x i8> @snork(<8 x i16> %arg) { -; CHECK-LABEL: define <16 x i8> @snork( +define <16 x i8> @knownbits_shuffle_bitcast_masked_shift(<8 x i16> %arg) { +; CHECK-LABEL: define <16 x i8> @knownbits_shuffle_bitcast_masked_shift( ; CHECK-SAME: <8 x i16> [[ARG:%.*]]) { ; CHECK-NEXT: [[BITCAST:%.*]] = bitcast <8 x i16> [[ARG]] to <16 x i8> ; CHECK-NEXT: [[SHUFFLEVECTOR:%.*]] = shufflevector <16 x i8> [[BITCAST]], <16 x i8> poison, <16 x i32> @@ -50,6 +51,7 @@ define <16 x i8> @snork(<8 x i16> %arg) { ; CHECK-NEXT: [[BITCAST7:%.*]] = bitcast <8 x i16> [[SHL6]] to <16 x i8> ; CHECK-NEXT: ret <16 x i8> [[BITCAST7]] ; + %bitcast = bitcast <8 x i16> %arg to <16 x i8> %shufflevector = shufflevector <16 x i8> %bitcast, <16 x i8> poison, <16 x i32> %bitcast1 = bitcast <16 x i8> %shufflevector to <8 x i16> @@ -67,8 +69,8 @@ define <16 x i8> @snork(<8 x i16> %arg) { ret <16 x i8> %and8 } -define <16 x i8> @wobble(<8 x i16> %arg) { -; CHECK-LABEL: define <16 x i8> @wobble( +define <16 x i8> @knownbits_shuffle_masked_nibble_shift(<8 x i16> %arg) { +; CHECK-LABEL: define <16 x i8> @knownbits_shuffle_masked_nibble_shift( ; CHECK-SAME: <8 x i16> [[ARG:%.*]]) { ; CHECK-NEXT: [[BITCAST:%.*]] = bitcast <8 x i16> [[ARG]] to <16 x i8> ; CHECK-NEXT: [[AND:%.*]] = and <16 x i8> [[BITCAST]], splat (i8 15) @@ -78,6 +80,7 @@ define <16 x i8> @wobble(<8 x i16> %arg) { ; CHECK-NEXT: [[BITCAST2:%.*]] = bitcast <8 x i16> [[SHL]] to <16 x i8> ; CHECK-NEXT: ret <16 x i8> [[BITCAST2]] ; + %bitcast = bitcast <8 x i16> %arg to <16 x i8> %and = and <16 x i8> %bitcast, splat (i8 15) %shufflevector = shufflevector <16 x i8> %and, <16 x i8> poison, <16 x i32> @@ -88,8 +91,8 @@ define <16 x i8> @wobble(<8 x i16> %arg) { ret <16 x i8> %and3 } -define <16 x i8> @wobble.1(<8 x i16> %arg) { -; CHECK-LABEL: define <16 x i8> @wobble.1( +define <16 x i8> @knownbits_reverse_shuffle_masked_shift(<8 x i16> %arg) { +; CHECK-LABEL: define <16 x i8> @knownbits_reverse_shuffle_masked_shift( ; CHECK-SAME: <8 x i16> [[ARG:%.*]]) { ; CHECK-NEXT: [[BITCAST:%.*]] = bitcast <8 x i16> [[ARG]] to <16 x i8> ; CHECK-NEXT: [[AND:%.*]] = and <16 x i8> [[BITCAST]], splat (i8 15) @@ -99,6 +102,7 @@ define <16 x i8> @wobble.1(<8 x i16> %arg) { ; CHECK-NEXT: [[BITCAST2:%.*]] = bitcast <8 x i16> [[SHL]] to <16 x i8> ; CHECK-NEXT: ret <16 x i8> [[BITCAST2]] ; + %bitcast = bitcast <8 x i16> %arg to <16 x i8> %and = and <16 x i8> %bitcast, splat (i8 15) %shufflevector = shufflevector <16 x i8> %and, <16 x i8> poison, <16 x i32> @@ -109,8 +113,8 @@ define <16 x i8> @wobble.1(<8 x i16> %arg) { ret <16 x i8> %and3 } -define <16 x i8> @pluto(<16 x i8> %arg) { -; CHECK-LABEL: define <16 x i8> @pluto( +define <16 x i8> @knownbits_interleave_mul_extract_bit(<16 x i8> %arg) { +; CHECK-LABEL: define <16 x i8> @knownbits_interleave_mul_extract_bit( ; CHECK-SAME: <16 x i8> [[ARG:%.*]]) { ; CHECK-NEXT: [[SHUFFLEVECTOR:%.*]] = shufflevector <16 x i8> [[ARG]], <16 x i8> , <16 x i32> ; CHECK-NEXT: [[BITCAST:%.*]] = bitcast <16 x i8> [[SHUFFLEVECTOR]] to <8 x i16> @@ -119,6 +123,7 @@ define <16 x i8> @pluto(<16 x i8> %arg) { ; CHECK-NEXT: [[BITCAST1:%.*]] = bitcast <8 x i16> [[LSHR]] to <16 x i8> ; CHECK-NEXT: ret <16 x i8> [[BITCAST1]] ; + %shufflevector = shufflevector <16 x i8> %arg, <16 x i8> , <16 x i32> %bitcast = bitcast <16 x i8> %shufflevector to <8 x i16> %mul = mul nuw <8 x i16> %bitcast, @@ -128,8 +133,8 @@ define <16 x i8> @pluto(<16 x i8> %arg) { ret <16 x i8> %and } -define <16 x i8> @wibble(<8 x i16> %arg) { -; CHECK-LABEL: define <16 x i8> @wibble( +define <16 x i8> @knownbits_reverse_shuffle_masked_ops(<8 x i16> %arg) { +; CHECK-LABEL: define <16 x i8> @knownbits_reverse_shuffle_masked_ops( ; CHECK-SAME: <8 x i16> [[ARG:%.*]]) { ; CHECK-NEXT: [[BITCAST:%.*]] = bitcast <8 x i16> [[ARG]] to <16 x i8> ; CHECK-NEXT: [[SHUFFLEVECTOR:%.*]] = shufflevector <16 x i8> [[BITCAST]], <16 x i8> poison, <16 x i32> @@ -146,6 +151,7 @@ define <16 x i8> @wibble(<8 x i16> %arg) { ; CHECK-NEXT: [[BITCAST7:%.*]] = bitcast <8 x i16> [[SHL6]] to <16 x i8> ; CHECK-NEXT: ret <16 x i8> [[BITCAST7]] ; + %bitcast = bitcast <8 x i16> %arg to <16 x i8> %shufflevector = shufflevector <16 x i8> %bitcast, <16 x i8> poison, <16 x i32> %bitcast1 = bitcast <16 x i8> %shufflevector to <8 x i16> @@ -163,8 +169,8 @@ define <16 x i8> @wibble(<8 x i16> %arg) { ret <16 x i8> %and8 } -define <16 x i8> @hoge(<4 x i32> %arg) { -; CHECK-LABEL: define <16 x i8> @hoge( +define <16 x i8> @knownbits_v4i32_to_v16i8_shuffle_masked_pipeline(<4 x i32> %arg) { +; CHECK-LABEL: define <16 x i8> @knownbits_v4i32_to_v16i8_shuffle_masked_pipeline( ; CHECK-SAME: <4 x i32> [[ARG:%.*]]) { ; CHECK-NEXT: [[BITCAST:%.*]] = bitcast <4 x i32> [[ARG]] to <16 x i8> ; CHECK-NEXT: [[SHUFFLEVECTOR:%.*]] = shufflevector <16 x i8> [[BITCAST]], <16 x i8> poison, <16 x i32> @@ -181,6 +187,7 @@ define <16 x i8> @hoge(<4 x i32> %arg) { ; CHECK-NEXT: [[BITCAST7:%.*]] = bitcast <8 x i16> [[SHL6]] to <16 x i8> ; CHECK-NEXT: ret <16 x i8> [[BITCAST7]] ; + %bitcast = bitcast <4 x i32> %arg to <16 x i8> %shufflevector = shufflevector <16 x i8> %bitcast, <16 x i8> poison, <16 x i32> %bitcast1 = bitcast <16 x i8> %shufflevector to <8 x i16> @@ -198,8 +205,8 @@ define <16 x i8> @hoge(<4 x i32> %arg) { ret <16 x i8> %and8 } -define { i32, i1 } @wombat.2(i32 %arg, i32 %arg1, i32 %arg2, i32 %arg3) { -; CHECK-LABEL: define { i32, i1 } @wombat.2( +define { i32, i1 } @knownbits_popcount_add_with_overflow(i32 %arg, i32 %arg1, i32 %arg2, i32 %arg3) { +; CHECK-LABEL: define { i32, i1 } @knownbits_popcount_add_with_overflow( ; CHECK-SAME: i32 [[ARG:%.*]], i32 [[ARG1:%.*]], i32 [[ARG2:%.*]], i32 [[ARG3:%.*]]) { ; CHECK-NEXT: [[INSERTELEMENT:%.*]] = insertelement <4 x i32> poison, i32 [[ARG2]], i64 0 ; CHECK-NEXT: [[INSERTELEMENT4:%.*]] = insertelement <4 x i32> [[INSERTELEMENT]], i32 [[ARG3]], i64 1 @@ -217,6 +224,7 @@ define { i32, i1 } @wombat.2(i32 %arg, i32 %arg1, i32 %arg2, i32 %arg3) { ; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { i32, i1 } { i32 poison, i1 false }, i32 [[CALL12]], 0 ; CHECK-NEXT: ret { i32, i1 } [[TMP1]] ; + %insertelement = insertelement <4 x i32> poison, i32 %arg2, i64 0 %insertelement4 = insertelement <4 x i32> %insertelement, i32 %arg3, i64 1 %bitcast = bitcast <4 x i32> %insertelement4 to <2 x i64> @@ -233,10 +241,53 @@ define { i32, i1 } @wombat.2(i32 %arg, i32 %arg1, i32 %arg2, i32 %arg3) { ret { i32, i1 } %call12 } -; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none) +define <16 x i8> @knownbits_shuffle_add_shift_v32i8(<32 x i8> %arg, <32 x i8> %arg1) local_unnamed_addr #0 { +; CHECK-LABEL: define <16 x i8> @knownbits_shuffle_add_shift_v32i8( +; CHECK-SAME: <32 x i8> [[ARG:%.*]], <32 x i8> [[ARG1:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { +; CHECK-NEXT: [[SHUFFLEVECTOR:%.*]] = shufflevector <32 x i8> [[ARG]], <32 x i8> poison, <16 x i32> +; CHECK-NEXT: [[SHUFFLEVECTOR2:%.*]] = shufflevector <32 x i8> [[ARG]], <32 x i8> poison, <16 x i32> +; CHECK-NEXT: [[ADD:%.*]] = add <16 x i8> [[SHUFFLEVECTOR]], [[SHUFFLEVECTOR2]] +; CHECK-NEXT: [[BITCAST:%.*]] = bitcast <16 x i8> [[ADD]] to <8 x i16> +; CHECK-NEXT: [[SHL:%.*]] = shl <8 x i16> [[BITCAST]], splat (i16 8) +; CHECK-NEXT: [[BITCAST3:%.*]] = bitcast <8 x i16> [[SHL]] to <16 x i8> +; CHECK-NEXT: [[BITCAST4:%.*]] = bitcast <32 x i8> [[ARG1]] to <16 x i16> +; CHECK-NEXT: [[SHUFFLEVECTOR5:%.*]] = shufflevector <16 x i16> [[BITCAST4]], <16 x i16> poison, <8 x i32> +; CHECK-NEXT: [[SHL6:%.*]] = shl <8 x i16> [[SHUFFLEVECTOR5]], splat (i16 8) +; CHECK-NEXT: [[BITCAST7:%.*]] = bitcast <8 x i16> [[SHL6]] to <16 x i8> +; CHECK-NEXT: [[BITCAST8:%.*]] = bitcast <32 x i8> [[ARG1]] to <16 x i16> +; CHECK-NEXT: [[SHUFFLEVECTOR9:%.*]] = shufflevector <16 x i16> [[BITCAST8]], <16 x i16> poison, <8 x i32> +; CHECK-NEXT: [[SHL10:%.*]] = shl <8 x i16> [[SHUFFLEVECTOR9]], splat (i16 8) +; CHECK-NEXT: [[BITCAST11:%.*]] = bitcast <8 x i16> [[SHL10]] to <16 x i8> +; CHECK-NEXT: [[ADD12:%.*]] = add <16 x i8> [[BITCAST11]], [[BITCAST7]] +; CHECK-NEXT: [[ADD13:%.*]] = add <16 x i8> [[ADD12]], [[BITCAST3]] +; CHECK-NEXT: ret <16 x i8> [[ADD13]] +; + + %shufflevector = shufflevector <32 x i8> %arg, <32 x i8> poison, <16 x i32> + %shufflevector2 = shufflevector <32 x i8> %arg, <32 x i8> poison, <16 x i32> + %add = add <16 x i8> %shufflevector, %shufflevector2 + %bitcast = bitcast <16 x i8> %add to <8 x i16> + %shl = shl <8 x i16> %bitcast, splat (i16 8) + %bitcast3 = bitcast <8 x i16> %shl to <16 x i8> + %bitcast4 = bitcast <32 x i8> %arg1 to <16 x i16> + %shufflevector5 = shufflevector <16 x i16> %bitcast4, <16 x i16> poison, <8 x i32> + %shl6 = shl <8 x i16> %shufflevector5, splat (i16 8) + %bitcast7 = bitcast <8 x i16> %shl6 to <16 x i8> + %bitcast8 = bitcast <32 x i8> %arg1 to <16 x i16> + %shufflevector9 = shufflevector <16 x i16> %bitcast8, <16 x i16> poison, <8 x i32> + %shl10 = shl <8 x i16> %shufflevector9, splat (i16 8) + %bitcast11 = bitcast <8 x i16> %shl10 to <16 x i8> + %add12 = add <16 x i8> %bitcast11, %bitcast7 + %add13 = add <16 x i8> %add12, %bitcast3 + %bitcast14 = bitcast <16 x i8> %add12 to <8 x i16> + %shl15 = shl <8 x i16> %bitcast14, splat (i16 8) + %bitcast16 = bitcast <8 x i16> %shl15 to <16 x i8> + %add17 = add <16 x i8> %add13, %bitcast16 + ret <16 x i8> %add17 +} + declare <2 x i64> @llvm.ctpop.v2i64(<2 x i64>) #0 -; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none) declare { i32, i1 } @llvm.uadd.with.overflow.i32(i32, i32) #0 attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } From d898cdd59aa23f28e57107e743e5f7856f572cc3 Mon Sep 17 00:00:00 2001 From: Abhishek Kaushik Date: Fri, 13 Jun 2025 21:58:53 +0530 Subject: [PATCH 07/10] Fix argument order for computeKnownBits --- llvm/lib/Analysis/ValueTracking.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 57780cbeeae07..73320b556f825 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -1375,8 +1375,8 @@ static void computeKnownBitsFromOperator(const Operator *I, KnownBits KnownSrc(SubBitWidth); for (unsigned i = 0; i != SubScale; ++i) { - computeKnownBits(I->getOperand(0), SubDemandedElts.shl(i), KnownSrc, - Depth + 1, Q); + computeKnownBits(I->getOperand(0), SubDemandedElts.shl(i), KnownSrc, Q, + Depth + 1); unsigned ShiftElt = IsLE ? i : SubScale - 1 - i; Known.insertBits(KnownSrc, ShiftElt * SubBitWidth); } @@ -1388,8 +1388,8 @@ static void computeKnownBitsFromOperator(const Operator *I, KnownBits KnownSrc(SubBitWidth); APInt SubDemandedElts = APIntOps::ScaleBitMask(DemandedElts, NumElts / SubScale); - computeKnownBits(I->getOperand(0), SubDemandedElts, KnownSrc, Depth + 1, - Q); + computeKnownBits(I->getOperand(0), SubDemandedElts, KnownSrc, Q, + Depth + 1); Known.Zero.setAllBits(); Known.One.setAllBits(); From aa34bd4e36bcff86d4ed39df3c134495a2108ebb Mon Sep 17 00:00:00 2001 From: Abhishek Kaushik Date: Fri, 13 Jun 2025 22:01:28 +0530 Subject: [PATCH 08/10] Rename test --- .../InstCombine/bitcast-known-bits.ll | 287 +++++++++++++++++ llvm/test/Transforms/InstCombine/pr125228.ll | 293 ------------------ 2 files changed, 287 insertions(+), 293 deletions(-) delete mode 100644 llvm/test/Transforms/InstCombine/pr125228.ll diff --git a/llvm/test/Transforms/InstCombine/bitcast-known-bits.ll b/llvm/test/Transforms/InstCombine/bitcast-known-bits.ll index 3e47e775e3a28..ae25b11c59943 100644 --- a/llvm/test/Transforms/InstCombine/bitcast-known-bits.ll +++ b/llvm/test/Transforms/InstCombine/bitcast-known-bits.ll @@ -132,3 +132,290 @@ define <16 x i8> @knownbits_shuffle_add_shift_v32i8(<16 x i8> %arg1, <8 x i16> % declare <2 x i64> @llvm.ctpop.v2i64(<2 x i64>) declare { i32, i1 } @llvm.uadd.with.overflow.i32(i32, i32) + +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 +; RUN: opt < %s -passes=instcombine -S | FileCheck %s + +; PR125228 + +define <16 x i8> @knownbits_bitcast_masked_shift(<16 x i8> %arg) { +; CHECK-LABEL: define <16 x i8> @knownbits_bitcast_masked_shift( +; CHECK-SAME: <16 x i8> [[ARG:%.*]]) { +; CHECK-NEXT: [[BITCAST:%.*]] = bitcast <16 x i8> [[ARG]] to <8 x i16> +; CHECK-NEXT: [[LSHR:%.*]] = lshr <8 x i16> [[BITCAST]], splat (i16 4) +; CHECK-NEXT: [[BITCAST1:%.*]] = bitcast <8 x i16> [[LSHR]] to <16 x i8> +; CHECK-NEXT: [[AND:%.*]] = and <16 x i8> [[BITCAST1]], splat (i8 3) +; CHECK-NEXT: [[SHL:%.*]] = shl <8 x i16> [[BITCAST]], splat (i16 4) +; CHECK-NEXT: [[BITCAST2:%.*]] = bitcast <8 x i16> [[SHL]] to <16 x i8> +; CHECK-NEXT: [[AND3:%.*]] = and <16 x i8> [[BITCAST2]], splat (i8 48) +; CHECK-NEXT: [[OR:%.*]] = or disjoint <16 x i8> [[AND]], [[AND3]] +; CHECK-NEXT: [[BITCAST4:%.*]] = bitcast <16 x i8> [[OR]] to <8 x i16> +; CHECK-NEXT: [[SHL5:%.*]] = shl nuw <8 x i16> [[BITCAST4]], splat (i16 2) +; CHECK-NEXT: [[BITCAST6:%.*]] = bitcast <8 x i16> [[SHL5]] to <16 x i8> +; CHECK-NEXT: ret <16 x i8> [[BITCAST6]] +; + %bitcast = bitcast <16 x i8> %arg to <8 x i16> + %lshr = lshr <8 x i16> %bitcast, splat (i16 4) + %bitcast1 = bitcast <8 x i16> %lshr to <16 x i8> + %and = and <16 x i8> %bitcast1, splat (i8 3) + %shl = shl <8 x i16> %bitcast, splat (i16 4) + %bitcast2 = bitcast <8 x i16> %shl to <16 x i8> + %and3 = and <16 x i8> %bitcast2, splat (i8 48) + %or = or disjoint <16 x i8> %and, %and3 + %bitcast4 = bitcast <16 x i8> %or to <8 x i16> + %shl5 = shl nuw <8 x i16> %bitcast4, splat (i16 2) + %bitcast6 = bitcast <8 x i16> %shl5 to <16 x i8> + %and7 = and <16 x i8> %bitcast6, splat (i8 -4) + ret <16 x i8> %and7 +} + +define <16 x i8> @knownbits_shuffle_bitcast_masked_shift(<8 x i16> %arg) { +; CHECK-LABEL: define <16 x i8> @knownbits_shuffle_bitcast_masked_shift( +; CHECK-SAME: <8 x i16> [[ARG:%.*]]) { +; CHECK-NEXT: [[BITCAST:%.*]] = bitcast <8 x i16> [[ARG]] to <16 x i8> +; CHECK-NEXT: [[SHUFFLEVECTOR:%.*]] = shufflevector <16 x i8> [[BITCAST]], <16 x i8> poison, <16 x i32> +; CHECK-NEXT: [[BITCAST1:%.*]] = bitcast <16 x i8> [[SHUFFLEVECTOR]] to <8 x i16> +; CHECK-NEXT: [[LSHR:%.*]] = lshr <8 x i16> [[BITCAST1]], splat (i16 4) +; CHECK-NEXT: [[BITCAST2:%.*]] = bitcast <8 x i16> [[LSHR]] to <16 x i8> +; CHECK-NEXT: [[AND:%.*]] = and <16 x i8> [[BITCAST2]], splat (i8 3) +; CHECK-NEXT: [[SHL:%.*]] = shl <8 x i16> [[BITCAST1]], splat (i16 4) +; CHECK-NEXT: [[BITCAST3:%.*]] = bitcast <8 x i16> [[SHL]] to <16 x i8> +; CHECK-NEXT: [[AND4:%.*]] = and <16 x i8> [[BITCAST3]], splat (i8 48) +; CHECK-NEXT: [[OR:%.*]] = or disjoint <16 x i8> [[AND]], [[AND4]] +; CHECK-NEXT: [[BITCAST5:%.*]] = bitcast <16 x i8> [[OR]] to <8 x i16> +; CHECK-NEXT: [[SHL6:%.*]] = shl nuw <8 x i16> [[BITCAST5]], splat (i16 2) +; CHECK-NEXT: [[BITCAST7:%.*]] = bitcast <8 x i16> [[SHL6]] to <16 x i8> +; CHECK-NEXT: ret <16 x i8> [[BITCAST7]] +; + %bitcast = bitcast <8 x i16> %arg to <16 x i8> + %shufflevector = shufflevector <16 x i8> %bitcast, <16 x i8> poison, <16 x i32> + %bitcast1 = bitcast <16 x i8> %shufflevector to <8 x i16> + %lshr = lshr <8 x i16> %bitcast1, splat (i16 4) + %bitcast2 = bitcast <8 x i16> %lshr to <16 x i8> + %and = and <16 x i8> %bitcast2, splat (i8 3) + %shl = shl <8 x i16> %bitcast1, splat (i16 4) + %bitcast3 = bitcast <8 x i16> %shl to <16 x i8> + %and4 = and <16 x i8> %bitcast3, splat (i8 48) + %or = or disjoint <16 x i8> %and, %and4 + %bitcast5 = bitcast <16 x i8> %or to <8 x i16> + %shl6 = shl nuw <8 x i16> %bitcast5, splat (i16 2) + %bitcast7 = bitcast <8 x i16> %shl6 to <16 x i8> + %and8 = and <16 x i8> %bitcast7, splat (i8 -4) + ret <16 x i8> %and8 +} + +define <16 x i8> @knownbits_shuffle_masked_nibble_shift(<8 x i16> %arg) { +; CHECK-LABEL: define <16 x i8> @knownbits_shuffle_masked_nibble_shift( +; CHECK-SAME: <8 x i16> [[ARG:%.*]]) { +; CHECK-NEXT: [[BITCAST:%.*]] = bitcast <8 x i16> [[ARG]] to <16 x i8> +; CHECK-NEXT: [[AND:%.*]] = and <16 x i8> [[BITCAST]], splat (i8 15) +; CHECK-NEXT: [[SHUFFLEVECTOR:%.*]] = shufflevector <16 x i8> [[AND]], <16 x i8> poison, <16 x i32> +; CHECK-NEXT: [[BITCAST1:%.*]] = bitcast <16 x i8> [[SHUFFLEVECTOR]] to <8 x i16> +; CHECK-NEXT: [[SHL:%.*]] = shl nuw <8 x i16> [[BITCAST1]], splat (i16 4) +; CHECK-NEXT: [[BITCAST2:%.*]] = bitcast <8 x i16> [[SHL]] to <16 x i8> +; CHECK-NEXT: ret <16 x i8> [[BITCAST2]] +; + %bitcast = bitcast <8 x i16> %arg to <16 x i8> + %and = and <16 x i8> %bitcast, splat (i8 15) + %shufflevector = shufflevector <16 x i8> %and, <16 x i8> poison, <16 x i32> + %bitcast1 = bitcast <16 x i8> %shufflevector to <8 x i16> + %shl = shl nuw <8 x i16> %bitcast1, splat (i16 4) + %bitcast2 = bitcast <8 x i16> %shl to <16 x i8> + %and3 = and <16 x i8> %bitcast2, splat (i8 -16) + ret <16 x i8> %and3 +} + +define <16 x i8> @knownbits_reverse_shuffle_masked_shift(<8 x i16> %arg) { +; CHECK-LABEL: define <16 x i8> @knownbits_reverse_shuffle_masked_shift( +; CHECK-SAME: <8 x i16> [[ARG:%.*]]) { +; CHECK-NEXT: [[BITCAST:%.*]] = bitcast <8 x i16> [[ARG]] to <16 x i8> +; CHECK-NEXT: [[AND:%.*]] = and <16 x i8> [[BITCAST]], splat (i8 15) +; CHECK-NEXT: [[SHUFFLEVECTOR:%.*]] = shufflevector <16 x i8> [[AND]], <16 x i8> poison, <16 x i32> +; CHECK-NEXT: [[BITCAST1:%.*]] = bitcast <16 x i8> [[SHUFFLEVECTOR]] to <8 x i16> +; CHECK-NEXT: [[SHL:%.*]] = shl nuw <8 x i16> [[BITCAST1]], splat (i16 4) +; CHECK-NEXT: [[BITCAST2:%.*]] = bitcast <8 x i16> [[SHL]] to <16 x i8> +; CHECK-NEXT: ret <16 x i8> [[BITCAST2]] +; + %bitcast = bitcast <8 x i16> %arg to <16 x i8> + %and = and <16 x i8> %bitcast, splat (i8 15) + %shufflevector = shufflevector <16 x i8> %and, <16 x i8> poison, <16 x i32> + %bitcast1 = bitcast <16 x i8> %shufflevector to <8 x i16> + %shl = shl nuw <8 x i16> %bitcast1, splat (i16 4) + %bitcast2 = bitcast <8 x i16> %shl to <16 x i8> + %and3 = and <16 x i8> %bitcast2, splat (i8 -16) + ret <16 x i8> %and3 +} + +define <16 x i8> @knownbits_interleave_mul_extract_bit(<16 x i8> %arg) { +; CHECK-LABEL: define <16 x i8> @knownbits_interleave_mul_extract_bit( +; CHECK-SAME: <16 x i8> [[ARG:%.*]]) { +; CHECK-NEXT: [[SHUFFLEVECTOR:%.*]] = shufflevector <16 x i8> [[ARG]], <16 x i8> , <16 x i32> +; CHECK-NEXT: [[BITCAST:%.*]] = bitcast <16 x i8> [[SHUFFLEVECTOR]] to <8 x i16> +; CHECK-NEXT: [[MUL:%.*]] = mul nuw <8 x i16> [[BITCAST]], +; CHECK-NEXT: [[LSHR:%.*]] = lshr <8 x i16> [[MUL]], splat (i16 15) +; CHECK-NEXT: [[BITCAST1:%.*]] = bitcast <8 x i16> [[LSHR]] to <16 x i8> +; CHECK-NEXT: ret <16 x i8> [[BITCAST1]] +; + %shufflevector = shufflevector <16 x i8> %arg, <16 x i8> , <16 x i32> + %bitcast = bitcast <16 x i8> %shufflevector to <8 x i16> + %mul = mul nuw <8 x i16> %bitcast, + %lshr = lshr <8 x i16> %mul, splat (i16 15) + %bitcast1 = bitcast <8 x i16> %lshr to <16 x i8> + %and = and <16 x i8> %bitcast1, splat (i8 1) + ret <16 x i8> %and +} + +define <16 x i8> @knownbits_reverse_shuffle_masked_ops(<8 x i16> %arg) { +; CHECK-LABEL: define <16 x i8> @knownbits_reverse_shuffle_masked_ops( +; CHECK-SAME: <8 x i16> [[ARG:%.*]]) { +; CHECK-NEXT: [[BITCAST:%.*]] = bitcast <8 x i16> [[ARG]] to <16 x i8> +; CHECK-NEXT: [[SHUFFLEVECTOR:%.*]] = shufflevector <16 x i8> [[BITCAST]], <16 x i8> poison, <16 x i32> +; CHECK-NEXT: [[BITCAST1:%.*]] = bitcast <16 x i8> [[SHUFFLEVECTOR]] to <8 x i16> +; CHECK-NEXT: [[LSHR:%.*]] = lshr <8 x i16> [[BITCAST1]], splat (i16 4) +; CHECK-NEXT: [[BITCAST2:%.*]] = bitcast <8 x i16> [[LSHR]] to <16 x i8> +; CHECK-NEXT: [[AND:%.*]] = and <16 x i8> [[BITCAST2]], splat (i8 3) +; CHECK-NEXT: [[SHL:%.*]] = shl <8 x i16> [[BITCAST1]], splat (i16 4) +; CHECK-NEXT: [[BITCAST3:%.*]] = bitcast <8 x i16> [[SHL]] to <16 x i8> +; CHECK-NEXT: [[AND4:%.*]] = and <16 x i8> [[BITCAST3]], splat (i8 48) +; CHECK-NEXT: [[OR:%.*]] = or disjoint <16 x i8> [[AND]], [[AND4]] +; CHECK-NEXT: [[BITCAST5:%.*]] = bitcast <16 x i8> [[OR]] to <8 x i16> +; CHECK-NEXT: [[SHL6:%.*]] = shl nuw <8 x i16> [[BITCAST5]], splat (i16 2) +; CHECK-NEXT: [[BITCAST7:%.*]] = bitcast <8 x i16> [[SHL6]] to <16 x i8> +; CHECK-NEXT: ret <16 x i8> [[BITCAST7]] +; + %bitcast = bitcast <8 x i16> %arg to <16 x i8> + %shufflevector = shufflevector <16 x i8> %bitcast, <16 x i8> poison, <16 x i32> + %bitcast1 = bitcast <16 x i8> %shufflevector to <8 x i16> + %lshr = lshr <8 x i16> %bitcast1, splat (i16 4) + %bitcast2 = bitcast <8 x i16> %lshr to <16 x i8> + %and = and <16 x i8> %bitcast2, splat (i8 3) + %shl = shl <8 x i16> %bitcast1, splat (i16 4) + %bitcast3 = bitcast <8 x i16> %shl to <16 x i8> + %and4 = and <16 x i8> %bitcast3, splat (i8 48) + %or = or disjoint <16 x i8> %and, %and4 + %bitcast5 = bitcast <16 x i8> %or to <8 x i16> + %shl6 = shl nuw <8 x i16> %bitcast5, splat (i16 2) + %bitcast7 = bitcast <8 x i16> %shl6 to <16 x i8> + %and8 = and <16 x i8> %bitcast7, splat (i8 -4) + ret <16 x i8> %and8 +} + +define <16 x i8> @knownbits_v4i32_to_v16i8_shuffle_masked_pipeline(<4 x i32> %arg) { +; CHECK-LABEL: define <16 x i8> @knownbits_v4i32_to_v16i8_shuffle_masked_pipeline( +; CHECK-SAME: <4 x i32> [[ARG:%.*]]) { +; CHECK-NEXT: [[BITCAST:%.*]] = bitcast <4 x i32> [[ARG]] to <16 x i8> +; CHECK-NEXT: [[SHUFFLEVECTOR:%.*]] = shufflevector <16 x i8> [[BITCAST]], <16 x i8> poison, <16 x i32> +; CHECK-NEXT: [[BITCAST1:%.*]] = bitcast <16 x i8> [[SHUFFLEVECTOR]] to <8 x i16> +; CHECK-NEXT: [[SHL:%.*]] = shl <8 x i16> [[BITCAST1]], splat (i16 4) +; CHECK-NEXT: [[BITCAST2:%.*]] = bitcast <8 x i16> [[SHL]] to <16 x i8> +; CHECK-NEXT: [[AND:%.*]] = and <16 x i8> [[BITCAST2]], splat (i8 48) +; CHECK-NEXT: [[LSHR:%.*]] = lshr <8 x i16> [[BITCAST1]], splat (i16 4) +; CHECK-NEXT: [[BITCAST3:%.*]] = bitcast <8 x i16> [[LSHR]] to <16 x i8> +; CHECK-NEXT: [[AND4:%.*]] = and <16 x i8> [[BITCAST3]], splat (i8 3) +; CHECK-NEXT: [[OR:%.*]] = or disjoint <16 x i8> [[AND4]], [[AND]] +; CHECK-NEXT: [[BITCAST5:%.*]] = bitcast <16 x i8> [[OR]] to <8 x i16> +; CHECK-NEXT: [[SHL6:%.*]] = shl nuw <8 x i16> [[BITCAST5]], splat (i16 2) +; CHECK-NEXT: [[BITCAST7:%.*]] = bitcast <8 x i16> [[SHL6]] to <16 x i8> +; CHECK-NEXT: ret <16 x i8> [[BITCAST7]] +; + %bitcast = bitcast <4 x i32> %arg to <16 x i8> + %shufflevector = shufflevector <16 x i8> %bitcast, <16 x i8> poison, <16 x i32> + %bitcast1 = bitcast <16 x i8> %shufflevector to <8 x i16> + %shl = shl <8 x i16> %bitcast1, splat (i16 4) + %bitcast2 = bitcast <8 x i16> %shl to <16 x i8> + %and = and <16 x i8> %bitcast2, splat (i8 48) + %lshr = lshr <8 x i16> %bitcast1, splat (i16 4) + %bitcast3 = bitcast <8 x i16> %lshr to <16 x i8> + %and4 = and <16 x i8> %bitcast3, splat (i8 3) + %or = or disjoint <16 x i8> %and4, %and + %bitcast5 = bitcast <16 x i8> %or to <8 x i16> + %shl6 = shl nuw <8 x i16> %bitcast5, splat (i16 2) + %bitcast7 = bitcast <8 x i16> %shl6 to <16 x i8> + %and8 = and <16 x i8> %bitcast7, splat (i8 -4) + ret <16 x i8> %and8 +} + +define { i32, i1 } @knownbits_popcount_add_with_overflow(i32 %arg, i32 %arg1, i32 %arg2, i32 %arg3) { +; CHECK-LABEL: define { i32, i1 } @knownbits_popcount_add_with_overflow( +; CHECK-SAME: i32 [[ARG:%.*]], i32 [[ARG1:%.*]], i32 [[ARG2:%.*]], i32 [[ARG3:%.*]]) { +; CHECK-NEXT: [[INSERTELEMENT:%.*]] = insertelement <4 x i32> poison, i32 [[ARG2]], i64 0 +; CHECK-NEXT: [[INSERTELEMENT4:%.*]] = insertelement <4 x i32> [[INSERTELEMENT]], i32 [[ARG3]], i64 1 +; CHECK-NEXT: [[BITCAST:%.*]] = bitcast <4 x i32> [[INSERTELEMENT4]] to <2 x i64> +; CHECK-NEXT: [[CALL:%.*]] = tail call range(i64 0, 65) <2 x i64> @llvm.ctpop.v2i64(<2 x i64> [[BITCAST]]) +; CHECK-NEXT: [[BITCAST5:%.*]] = bitcast <2 x i64> [[CALL]] to <4 x i32> +; CHECK-NEXT: [[EXTRACTELEMENT:%.*]] = extractelement <4 x i32> [[BITCAST5]], i64 0 +; CHECK-NEXT: [[INSERTELEMENT6:%.*]] = insertelement <4 x i32> poison, i32 [[ARG]], i64 0 +; CHECK-NEXT: [[INSERTELEMENT7:%.*]] = insertelement <4 x i32> [[INSERTELEMENT6]], i32 [[ARG1]], i64 1 +; CHECK-NEXT: [[BITCAST8:%.*]] = bitcast <4 x i32> [[INSERTELEMENT7]] to <2 x i64> +; CHECK-NEXT: [[CALL9:%.*]] = tail call range(i64 0, 65) <2 x i64> @llvm.ctpop.v2i64(<2 x i64> [[BITCAST8]]) +; CHECK-NEXT: [[BITCAST10:%.*]] = bitcast <2 x i64> [[CALL9]] to <4 x i32> +; CHECK-NEXT: [[EXTRACTELEMENT11:%.*]] = extractelement <4 x i32> [[BITCAST10]], i64 0 +; CHECK-NEXT: [[CALL12:%.*]] = add nuw nsw i32 [[EXTRACTELEMENT]], [[EXTRACTELEMENT11]] +; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { i32, i1 } { i32 poison, i1 false }, i32 [[CALL12]], 0 +; CHECK-NEXT: ret { i32, i1 } [[TMP1]] +; + %insertelement = insertelement <4 x i32> poison, i32 %arg2, i64 0 + %insertelement4 = insertelement <4 x i32> %insertelement, i32 %arg3, i64 1 + %bitcast = bitcast <4 x i32> %insertelement4 to <2 x i64> + %call = tail call <2 x i64> @llvm.ctpop.v2i64(<2 x i64> %bitcast) + %bitcast5 = bitcast <2 x i64> %call to <4 x i32> + %extractelement = extractelement <4 x i32> %bitcast5, i64 0 + %insertelement6 = insertelement <4 x i32> poison, i32 %arg, i64 0 + %insertelement7 = insertelement <4 x i32> %insertelement6, i32 %arg1, i64 1 + %bitcast8 = bitcast <4 x i32> %insertelement7 to <2 x i64> + %call9 = tail call <2 x i64> @llvm.ctpop.v2i64(<2 x i64> %bitcast8) + %bitcast10 = bitcast <2 x i64> %call9 to <4 x i32> + %extractelement11 = extractelement <4 x i32> %bitcast10, i64 0 + %call12 = tail call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %extractelement, i32 %extractelement11) + ret { i32, i1 } %call12 +} + +define <16 x i8> @knownbits_shuffle_add_shift_v32i8(<32 x i8> %arg, <32 x i8> %arg1) local_unnamed_addr #0 { +; CHECK-LABEL: define <16 x i8> @knownbits_shuffle_add_shift_v32i8( +; CHECK-SAME: <32 x i8> [[ARG:%.*]], <32 x i8> [[ARG1:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { +; CHECK-NEXT: [[SHUFFLEVECTOR:%.*]] = shufflevector <32 x i8> [[ARG]], <32 x i8> poison, <16 x i32> +; CHECK-NEXT: [[SHUFFLEVECTOR2:%.*]] = shufflevector <32 x i8> [[ARG]], <32 x i8> poison, <16 x i32> +; CHECK-NEXT: [[ADD:%.*]] = add <16 x i8> [[SHUFFLEVECTOR]], [[SHUFFLEVECTOR2]] +; CHECK-NEXT: [[BITCAST:%.*]] = bitcast <16 x i8> [[ADD]] to <8 x i16> +; CHECK-NEXT: [[SHL:%.*]] = shl <8 x i16> [[BITCAST]], splat (i16 8) +; CHECK-NEXT: [[BITCAST3:%.*]] = bitcast <8 x i16> [[SHL]] to <16 x i8> +; CHECK-NEXT: [[BITCAST4:%.*]] = bitcast <32 x i8> [[ARG1]] to <16 x i16> +; CHECK-NEXT: [[SHUFFLEVECTOR5:%.*]] = shufflevector <16 x i16> [[BITCAST4]], <16 x i16> poison, <8 x i32> +; CHECK-NEXT: [[SHL6:%.*]] = shl <8 x i16> [[SHUFFLEVECTOR5]], splat (i16 8) +; CHECK-NEXT: [[BITCAST7:%.*]] = bitcast <8 x i16> [[SHL6]] to <16 x i8> +; CHECK-NEXT: [[BITCAST8:%.*]] = bitcast <32 x i8> [[ARG1]] to <16 x i16> +; CHECK-NEXT: [[SHUFFLEVECTOR9:%.*]] = shufflevector <16 x i16> [[BITCAST8]], <16 x i16> poison, <8 x i32> +; CHECK-NEXT: [[SHL10:%.*]] = shl <8 x i16> [[SHUFFLEVECTOR9]], splat (i16 8) +; CHECK-NEXT: [[BITCAST11:%.*]] = bitcast <8 x i16> [[SHL10]] to <16 x i8> +; CHECK-NEXT: [[ADD12:%.*]] = add <16 x i8> [[BITCAST11]], [[BITCAST7]] +; CHECK-NEXT: [[ADD17:%.*]] = add <16 x i8> [[ADD12]], [[BITCAST3]] +; CHECK-NEXT: ret <16 x i8> [[ADD17]] +; + %shufflevector = shufflevector <32 x i8> %arg, <32 x i8> poison, <16 x i32> + %shufflevector2 = shufflevector <32 x i8> %arg, <32 x i8> poison, <16 x i32> + %add = add <16 x i8> %shufflevector, %shufflevector2 + %bitcast = bitcast <16 x i8> %add to <8 x i16> + %shl = shl <8 x i16> %bitcast, splat (i16 8) + %bitcast3 = bitcast <8 x i16> %shl to <16 x i8> + %bitcast4 = bitcast <32 x i8> %arg1 to <16 x i16> + %shufflevector5 = shufflevector <16 x i16> %bitcast4, <16 x i16> poison, <8 x i32> + %shl6 = shl <8 x i16> %shufflevector5, splat (i16 8) + %bitcast7 = bitcast <8 x i16> %shl6 to <16 x i8> + %bitcast8 = bitcast <32 x i8> %arg1 to <16 x i16> + %shufflevector9 = shufflevector <16 x i16> %bitcast8, <16 x i16> poison, <8 x i32> + %shl10 = shl <8 x i16> %shufflevector9, splat (i16 8) + %bitcast11 = bitcast <8 x i16> %shl10 to <16 x i8> + %add12 = add <16 x i8> %bitcast11, %bitcast7 + %add13 = add <16 x i8> %add12, %bitcast3 + %bitcast14 = bitcast <16 x i8> %add12 to <8 x i16> + %shl15 = shl <8 x i16> %bitcast14, splat (i16 8) + %bitcast16 = bitcast <8 x i16> %shl15 to <16 x i8> + %add17 = add <16 x i8> %add13, %bitcast16 + ret <16 x i8> %add17 +} + +declare <2 x i64> @llvm.ctpop.v2i64(<2 x i64>) #0 + +declare { i32, i1 } @llvm.uadd.with.overflow.i32(i32, i32) #0 + +attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } diff --git a/llvm/test/Transforms/InstCombine/pr125228.ll b/llvm/test/Transforms/InstCombine/pr125228.ll deleted file mode 100644 index 5b1b6c29c0201..0000000000000 --- a/llvm/test/Transforms/InstCombine/pr125228.ll +++ /dev/null @@ -1,293 +0,0 @@ -; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 -; RUN: opt < %s -passes=instcombine -S | FileCheck %s - -define <16 x i8> @knownbits_bitcast_masked_shift(<16 x i8> %arg) { -; CHECK-LABEL: define <16 x i8> @knownbits_bitcast_masked_shift( -; CHECK-SAME: <16 x i8> [[ARG:%.*]]) { -; CHECK-NEXT: [[BITCAST:%.*]] = bitcast <16 x i8> [[ARG]] to <8 x i16> -; CHECK-NEXT: [[LSHR:%.*]] = lshr <8 x i16> [[BITCAST]], splat (i16 4) -; CHECK-NEXT: [[BITCAST1:%.*]] = bitcast <8 x i16> [[LSHR]] to <16 x i8> -; CHECK-NEXT: [[AND:%.*]] = and <16 x i8> [[BITCAST1]], splat (i8 3) -; CHECK-NEXT: [[SHL:%.*]] = shl <8 x i16> [[BITCAST]], splat (i16 4) -; CHECK-NEXT: [[BITCAST2:%.*]] = bitcast <8 x i16> [[SHL]] to <16 x i8> -; CHECK-NEXT: [[AND3:%.*]] = and <16 x i8> [[BITCAST2]], splat (i8 48) -; CHECK-NEXT: [[OR:%.*]] = or disjoint <16 x i8> [[AND]], [[AND3]] -; CHECK-NEXT: [[BITCAST4:%.*]] = bitcast <16 x i8> [[OR]] to <8 x i16> -; CHECK-NEXT: [[SHL5:%.*]] = shl nuw <8 x i16> [[BITCAST4]], splat (i16 2) -; CHECK-NEXT: [[BITCAST6:%.*]] = bitcast <8 x i16> [[SHL5]] to <16 x i8> -; CHECK-NEXT: ret <16 x i8> [[BITCAST6]] -; - - %bitcast = bitcast <16 x i8> %arg to <8 x i16> - %lshr = lshr <8 x i16> %bitcast, splat (i16 4) - %bitcast1 = bitcast <8 x i16> %lshr to <16 x i8> - %and = and <16 x i8> %bitcast1, splat (i8 3) - %shl = shl <8 x i16> %bitcast, splat (i16 4) - %bitcast2 = bitcast <8 x i16> %shl to <16 x i8> - %and3 = and <16 x i8> %bitcast2, splat (i8 48) - %or = or disjoint <16 x i8> %and, %and3 - %bitcast4 = bitcast <16 x i8> %or to <8 x i16> - %shl5 = shl nuw <8 x i16> %bitcast4, splat (i16 2) - %bitcast6 = bitcast <8 x i16> %shl5 to <16 x i8> - %and7 = and <16 x i8> %bitcast6, splat (i8 -4) - ret <16 x i8> %and7 -} - -define <16 x i8> @knownbits_shuffle_bitcast_masked_shift(<8 x i16> %arg) { -; CHECK-LABEL: define <16 x i8> @knownbits_shuffle_bitcast_masked_shift( -; CHECK-SAME: <8 x i16> [[ARG:%.*]]) { -; CHECK-NEXT: [[BITCAST:%.*]] = bitcast <8 x i16> [[ARG]] to <16 x i8> -; CHECK-NEXT: [[SHUFFLEVECTOR:%.*]] = shufflevector <16 x i8> [[BITCAST]], <16 x i8> poison, <16 x i32> -; CHECK-NEXT: [[BITCAST1:%.*]] = bitcast <16 x i8> [[SHUFFLEVECTOR]] to <8 x i16> -; CHECK-NEXT: [[LSHR:%.*]] = lshr <8 x i16> [[BITCAST1]], splat (i16 4) -; CHECK-NEXT: [[BITCAST2:%.*]] = bitcast <8 x i16> [[LSHR]] to <16 x i8> -; CHECK-NEXT: [[AND:%.*]] = and <16 x i8> [[BITCAST2]], splat (i8 3) -; CHECK-NEXT: [[SHL:%.*]] = shl <8 x i16> [[BITCAST1]], splat (i16 4) -; CHECK-NEXT: [[BITCAST3:%.*]] = bitcast <8 x i16> [[SHL]] to <16 x i8> -; CHECK-NEXT: [[AND4:%.*]] = and <16 x i8> [[BITCAST3]], splat (i8 48) -; CHECK-NEXT: [[OR:%.*]] = or disjoint <16 x i8> [[AND]], [[AND4]] -; CHECK-NEXT: [[BITCAST5:%.*]] = bitcast <16 x i8> [[OR]] to <8 x i16> -; CHECK-NEXT: [[SHL6:%.*]] = shl nuw <8 x i16> [[BITCAST5]], splat (i16 2) -; CHECK-NEXT: [[BITCAST7:%.*]] = bitcast <8 x i16> [[SHL6]] to <16 x i8> -; CHECK-NEXT: ret <16 x i8> [[BITCAST7]] -; - - %bitcast = bitcast <8 x i16> %arg to <16 x i8> - %shufflevector = shufflevector <16 x i8> %bitcast, <16 x i8> poison, <16 x i32> - %bitcast1 = bitcast <16 x i8> %shufflevector to <8 x i16> - %lshr = lshr <8 x i16> %bitcast1, splat (i16 4) - %bitcast2 = bitcast <8 x i16> %lshr to <16 x i8> - %and = and <16 x i8> %bitcast2, splat (i8 3) - %shl = shl <8 x i16> %bitcast1, splat (i16 4) - %bitcast3 = bitcast <8 x i16> %shl to <16 x i8> - %and4 = and <16 x i8> %bitcast3, splat (i8 48) - %or = or disjoint <16 x i8> %and, %and4 - %bitcast5 = bitcast <16 x i8> %or to <8 x i16> - %shl6 = shl nuw <8 x i16> %bitcast5, splat (i16 2) - %bitcast7 = bitcast <8 x i16> %shl6 to <16 x i8> - %and8 = and <16 x i8> %bitcast7, splat (i8 -4) - ret <16 x i8> %and8 -} - -define <16 x i8> @knownbits_shuffle_masked_nibble_shift(<8 x i16> %arg) { -; CHECK-LABEL: define <16 x i8> @knownbits_shuffle_masked_nibble_shift( -; CHECK-SAME: <8 x i16> [[ARG:%.*]]) { -; CHECK-NEXT: [[BITCAST:%.*]] = bitcast <8 x i16> [[ARG]] to <16 x i8> -; CHECK-NEXT: [[AND:%.*]] = and <16 x i8> [[BITCAST]], splat (i8 15) -; CHECK-NEXT: [[SHUFFLEVECTOR:%.*]] = shufflevector <16 x i8> [[AND]], <16 x i8> poison, <16 x i32> -; CHECK-NEXT: [[BITCAST1:%.*]] = bitcast <16 x i8> [[SHUFFLEVECTOR]] to <8 x i16> -; CHECK-NEXT: [[SHL:%.*]] = shl nuw <8 x i16> [[BITCAST1]], splat (i16 4) -; CHECK-NEXT: [[BITCAST2:%.*]] = bitcast <8 x i16> [[SHL]] to <16 x i8> -; CHECK-NEXT: ret <16 x i8> [[BITCAST2]] -; - - %bitcast = bitcast <8 x i16> %arg to <16 x i8> - %and = and <16 x i8> %bitcast, splat (i8 15) - %shufflevector = shufflevector <16 x i8> %and, <16 x i8> poison, <16 x i32> - %bitcast1 = bitcast <16 x i8> %shufflevector to <8 x i16> - %shl = shl nuw <8 x i16> %bitcast1, splat (i16 4) - %bitcast2 = bitcast <8 x i16> %shl to <16 x i8> - %and3 = and <16 x i8> %bitcast2, splat (i8 -16) - ret <16 x i8> %and3 -} - -define <16 x i8> @knownbits_reverse_shuffle_masked_shift(<8 x i16> %arg) { -; CHECK-LABEL: define <16 x i8> @knownbits_reverse_shuffle_masked_shift( -; CHECK-SAME: <8 x i16> [[ARG:%.*]]) { -; CHECK-NEXT: [[BITCAST:%.*]] = bitcast <8 x i16> [[ARG]] to <16 x i8> -; CHECK-NEXT: [[AND:%.*]] = and <16 x i8> [[BITCAST]], splat (i8 15) -; CHECK-NEXT: [[SHUFFLEVECTOR:%.*]] = shufflevector <16 x i8> [[AND]], <16 x i8> poison, <16 x i32> -; CHECK-NEXT: [[BITCAST1:%.*]] = bitcast <16 x i8> [[SHUFFLEVECTOR]] to <8 x i16> -; CHECK-NEXT: [[SHL:%.*]] = shl nuw <8 x i16> [[BITCAST1]], splat (i16 4) -; CHECK-NEXT: [[BITCAST2:%.*]] = bitcast <8 x i16> [[SHL]] to <16 x i8> -; CHECK-NEXT: ret <16 x i8> [[BITCAST2]] -; - - %bitcast = bitcast <8 x i16> %arg to <16 x i8> - %and = and <16 x i8> %bitcast, splat (i8 15) - %shufflevector = shufflevector <16 x i8> %and, <16 x i8> poison, <16 x i32> - %bitcast1 = bitcast <16 x i8> %shufflevector to <8 x i16> - %shl = shl nuw <8 x i16> %bitcast1, splat (i16 4) - %bitcast2 = bitcast <8 x i16> %shl to <16 x i8> - %and3 = and <16 x i8> %bitcast2, splat (i8 -16) - ret <16 x i8> %and3 -} - -define <16 x i8> @knownbits_interleave_mul_extract_bit(<16 x i8> %arg) { -; CHECK-LABEL: define <16 x i8> @knownbits_interleave_mul_extract_bit( -; CHECK-SAME: <16 x i8> [[ARG:%.*]]) { -; CHECK-NEXT: [[SHUFFLEVECTOR:%.*]] = shufflevector <16 x i8> [[ARG]], <16 x i8> , <16 x i32> -; CHECK-NEXT: [[BITCAST:%.*]] = bitcast <16 x i8> [[SHUFFLEVECTOR]] to <8 x i16> -; CHECK-NEXT: [[MUL:%.*]] = mul nuw <8 x i16> [[BITCAST]], -; CHECK-NEXT: [[LSHR:%.*]] = lshr <8 x i16> [[MUL]], splat (i16 15) -; CHECK-NEXT: [[BITCAST1:%.*]] = bitcast <8 x i16> [[LSHR]] to <16 x i8> -; CHECK-NEXT: ret <16 x i8> [[BITCAST1]] -; - - %shufflevector = shufflevector <16 x i8> %arg, <16 x i8> , <16 x i32> - %bitcast = bitcast <16 x i8> %shufflevector to <8 x i16> - %mul = mul nuw <8 x i16> %bitcast, - %lshr = lshr <8 x i16> %mul, splat (i16 15) - %bitcast1 = bitcast <8 x i16> %lshr to <16 x i8> - %and = and <16 x i8> %bitcast1, splat (i8 1) - ret <16 x i8> %and -} - -define <16 x i8> @knownbits_reverse_shuffle_masked_ops(<8 x i16> %arg) { -; CHECK-LABEL: define <16 x i8> @knownbits_reverse_shuffle_masked_ops( -; CHECK-SAME: <8 x i16> [[ARG:%.*]]) { -; CHECK-NEXT: [[BITCAST:%.*]] = bitcast <8 x i16> [[ARG]] to <16 x i8> -; CHECK-NEXT: [[SHUFFLEVECTOR:%.*]] = shufflevector <16 x i8> [[BITCAST]], <16 x i8> poison, <16 x i32> -; CHECK-NEXT: [[BITCAST1:%.*]] = bitcast <16 x i8> [[SHUFFLEVECTOR]] to <8 x i16> -; CHECK-NEXT: [[LSHR:%.*]] = lshr <8 x i16> [[BITCAST1]], splat (i16 4) -; CHECK-NEXT: [[BITCAST2:%.*]] = bitcast <8 x i16> [[LSHR]] to <16 x i8> -; CHECK-NEXT: [[AND:%.*]] = and <16 x i8> [[BITCAST2]], splat (i8 3) -; CHECK-NEXT: [[SHL:%.*]] = shl <8 x i16> [[BITCAST1]], splat (i16 4) -; CHECK-NEXT: [[BITCAST3:%.*]] = bitcast <8 x i16> [[SHL]] to <16 x i8> -; CHECK-NEXT: [[AND4:%.*]] = and <16 x i8> [[BITCAST3]], splat (i8 48) -; CHECK-NEXT: [[OR:%.*]] = or disjoint <16 x i8> [[AND]], [[AND4]] -; CHECK-NEXT: [[BITCAST5:%.*]] = bitcast <16 x i8> [[OR]] to <8 x i16> -; CHECK-NEXT: [[SHL6:%.*]] = shl nuw <8 x i16> [[BITCAST5]], splat (i16 2) -; CHECK-NEXT: [[BITCAST7:%.*]] = bitcast <8 x i16> [[SHL6]] to <16 x i8> -; CHECK-NEXT: ret <16 x i8> [[BITCAST7]] -; - - %bitcast = bitcast <8 x i16> %arg to <16 x i8> - %shufflevector = shufflevector <16 x i8> %bitcast, <16 x i8> poison, <16 x i32> - %bitcast1 = bitcast <16 x i8> %shufflevector to <8 x i16> - %lshr = lshr <8 x i16> %bitcast1, splat (i16 4) - %bitcast2 = bitcast <8 x i16> %lshr to <16 x i8> - %and = and <16 x i8> %bitcast2, splat (i8 3) - %shl = shl <8 x i16> %bitcast1, splat (i16 4) - %bitcast3 = bitcast <8 x i16> %shl to <16 x i8> - %and4 = and <16 x i8> %bitcast3, splat (i8 48) - %or = or disjoint <16 x i8> %and, %and4 - %bitcast5 = bitcast <16 x i8> %or to <8 x i16> - %shl6 = shl nuw <8 x i16> %bitcast5, splat (i16 2) - %bitcast7 = bitcast <8 x i16> %shl6 to <16 x i8> - %and8 = and <16 x i8> %bitcast7, splat (i8 -4) - ret <16 x i8> %and8 -} - -define <16 x i8> @knownbits_v4i32_to_v16i8_shuffle_masked_pipeline(<4 x i32> %arg) { -; CHECK-LABEL: define <16 x i8> @knownbits_v4i32_to_v16i8_shuffle_masked_pipeline( -; CHECK-SAME: <4 x i32> [[ARG:%.*]]) { -; CHECK-NEXT: [[BITCAST:%.*]] = bitcast <4 x i32> [[ARG]] to <16 x i8> -; CHECK-NEXT: [[SHUFFLEVECTOR:%.*]] = shufflevector <16 x i8> [[BITCAST]], <16 x i8> poison, <16 x i32> -; CHECK-NEXT: [[BITCAST1:%.*]] = bitcast <16 x i8> [[SHUFFLEVECTOR]] to <8 x i16> -; CHECK-NEXT: [[SHL:%.*]] = shl <8 x i16> [[BITCAST1]], splat (i16 4) -; CHECK-NEXT: [[BITCAST2:%.*]] = bitcast <8 x i16> [[SHL]] to <16 x i8> -; CHECK-NEXT: [[AND:%.*]] = and <16 x i8> [[BITCAST2]], splat (i8 48) -; CHECK-NEXT: [[LSHR:%.*]] = lshr <8 x i16> [[BITCAST1]], splat (i16 4) -; CHECK-NEXT: [[BITCAST3:%.*]] = bitcast <8 x i16> [[LSHR]] to <16 x i8> -; CHECK-NEXT: [[AND4:%.*]] = and <16 x i8> [[BITCAST3]], splat (i8 3) -; CHECK-NEXT: [[OR:%.*]] = or disjoint <16 x i8> [[AND4]], [[AND]] -; CHECK-NEXT: [[BITCAST5:%.*]] = bitcast <16 x i8> [[OR]] to <8 x i16> -; CHECK-NEXT: [[SHL6:%.*]] = shl nuw <8 x i16> [[BITCAST5]], splat (i16 2) -; CHECK-NEXT: [[BITCAST7:%.*]] = bitcast <8 x i16> [[SHL6]] to <16 x i8> -; CHECK-NEXT: ret <16 x i8> [[BITCAST7]] -; - - %bitcast = bitcast <4 x i32> %arg to <16 x i8> - %shufflevector = shufflevector <16 x i8> %bitcast, <16 x i8> poison, <16 x i32> - %bitcast1 = bitcast <16 x i8> %shufflevector to <8 x i16> - %shl = shl <8 x i16> %bitcast1, splat (i16 4) - %bitcast2 = bitcast <8 x i16> %shl to <16 x i8> - %and = and <16 x i8> %bitcast2, splat (i8 48) - %lshr = lshr <8 x i16> %bitcast1, splat (i16 4) - %bitcast3 = bitcast <8 x i16> %lshr to <16 x i8> - %and4 = and <16 x i8> %bitcast3, splat (i8 3) - %or = or disjoint <16 x i8> %and4, %and - %bitcast5 = bitcast <16 x i8> %or to <8 x i16> - %shl6 = shl nuw <8 x i16> %bitcast5, splat (i16 2) - %bitcast7 = bitcast <8 x i16> %shl6 to <16 x i8> - %and8 = and <16 x i8> %bitcast7, splat (i8 -4) - ret <16 x i8> %and8 -} - -define { i32, i1 } @knownbits_popcount_add_with_overflow(i32 %arg, i32 %arg1, i32 %arg2, i32 %arg3) { -; CHECK-LABEL: define { i32, i1 } @knownbits_popcount_add_with_overflow( -; CHECK-SAME: i32 [[ARG:%.*]], i32 [[ARG1:%.*]], i32 [[ARG2:%.*]], i32 [[ARG3:%.*]]) { -; CHECK-NEXT: [[INSERTELEMENT:%.*]] = insertelement <4 x i32> poison, i32 [[ARG2]], i64 0 -; CHECK-NEXT: [[INSERTELEMENT4:%.*]] = insertelement <4 x i32> [[INSERTELEMENT]], i32 [[ARG3]], i64 1 -; CHECK-NEXT: [[BITCAST:%.*]] = bitcast <4 x i32> [[INSERTELEMENT4]] to <2 x i64> -; CHECK-NEXT: [[CALL:%.*]] = tail call range(i64 0, 65) <2 x i64> @llvm.ctpop.v2i64(<2 x i64> [[BITCAST]]) -; CHECK-NEXT: [[BITCAST5:%.*]] = bitcast <2 x i64> [[CALL]] to <4 x i32> -; CHECK-NEXT: [[EXTRACTELEMENT:%.*]] = extractelement <4 x i32> [[BITCAST5]], i64 0 -; CHECK-NEXT: [[INSERTELEMENT6:%.*]] = insertelement <4 x i32> poison, i32 [[ARG]], i64 0 -; CHECK-NEXT: [[INSERTELEMENT7:%.*]] = insertelement <4 x i32> [[INSERTELEMENT6]], i32 [[ARG1]], i64 1 -; CHECK-NEXT: [[BITCAST8:%.*]] = bitcast <4 x i32> [[INSERTELEMENT7]] to <2 x i64> -; CHECK-NEXT: [[CALL9:%.*]] = tail call range(i64 0, 65) <2 x i64> @llvm.ctpop.v2i64(<2 x i64> [[BITCAST8]]) -; CHECK-NEXT: [[BITCAST10:%.*]] = bitcast <2 x i64> [[CALL9]] to <4 x i32> -; CHECK-NEXT: [[EXTRACTELEMENT11:%.*]] = extractelement <4 x i32> [[BITCAST10]], i64 0 -; CHECK-NEXT: [[CALL12:%.*]] = add nuw nsw i32 [[EXTRACTELEMENT]], [[EXTRACTELEMENT11]] -; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { i32, i1 } { i32 poison, i1 false }, i32 [[CALL12]], 0 -; CHECK-NEXT: ret { i32, i1 } [[TMP1]] -; - - %insertelement = insertelement <4 x i32> poison, i32 %arg2, i64 0 - %insertelement4 = insertelement <4 x i32> %insertelement, i32 %arg3, i64 1 - %bitcast = bitcast <4 x i32> %insertelement4 to <2 x i64> - %call = tail call <2 x i64> @llvm.ctpop.v2i64(<2 x i64> %bitcast) - %bitcast5 = bitcast <2 x i64> %call to <4 x i32> - %extractelement = extractelement <4 x i32> %bitcast5, i64 0 - %insertelement6 = insertelement <4 x i32> poison, i32 %arg, i64 0 - %insertelement7 = insertelement <4 x i32> %insertelement6, i32 %arg1, i64 1 - %bitcast8 = bitcast <4 x i32> %insertelement7 to <2 x i64> - %call9 = tail call <2 x i64> @llvm.ctpop.v2i64(<2 x i64> %bitcast8) - %bitcast10 = bitcast <2 x i64> %call9 to <4 x i32> - %extractelement11 = extractelement <4 x i32> %bitcast10, i64 0 - %call12 = tail call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %extractelement, i32 %extractelement11) - ret { i32, i1 } %call12 -} - -define <16 x i8> @knownbits_shuffle_add_shift_v32i8(<32 x i8> %arg, <32 x i8> %arg1) local_unnamed_addr #0 { -; CHECK-LABEL: define <16 x i8> @knownbits_shuffle_add_shift_v32i8( -; CHECK-SAME: <32 x i8> [[ARG:%.*]], <32 x i8> [[ARG1:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { -; CHECK-NEXT: [[SHUFFLEVECTOR:%.*]] = shufflevector <32 x i8> [[ARG]], <32 x i8> poison, <16 x i32> -; CHECK-NEXT: [[SHUFFLEVECTOR2:%.*]] = shufflevector <32 x i8> [[ARG]], <32 x i8> poison, <16 x i32> -; CHECK-NEXT: [[ADD:%.*]] = add <16 x i8> [[SHUFFLEVECTOR]], [[SHUFFLEVECTOR2]] -; CHECK-NEXT: [[BITCAST:%.*]] = bitcast <16 x i8> [[ADD]] to <8 x i16> -; CHECK-NEXT: [[SHL:%.*]] = shl <8 x i16> [[BITCAST]], splat (i16 8) -; CHECK-NEXT: [[BITCAST3:%.*]] = bitcast <8 x i16> [[SHL]] to <16 x i8> -; CHECK-NEXT: [[BITCAST4:%.*]] = bitcast <32 x i8> [[ARG1]] to <16 x i16> -; CHECK-NEXT: [[SHUFFLEVECTOR5:%.*]] = shufflevector <16 x i16> [[BITCAST4]], <16 x i16> poison, <8 x i32> -; CHECK-NEXT: [[SHL6:%.*]] = shl <8 x i16> [[SHUFFLEVECTOR5]], splat (i16 8) -; CHECK-NEXT: [[BITCAST7:%.*]] = bitcast <8 x i16> [[SHL6]] to <16 x i8> -; CHECK-NEXT: [[BITCAST8:%.*]] = bitcast <32 x i8> [[ARG1]] to <16 x i16> -; CHECK-NEXT: [[SHUFFLEVECTOR9:%.*]] = shufflevector <16 x i16> [[BITCAST8]], <16 x i16> poison, <8 x i32> -; CHECK-NEXT: [[SHL10:%.*]] = shl <8 x i16> [[SHUFFLEVECTOR9]], splat (i16 8) -; CHECK-NEXT: [[BITCAST11:%.*]] = bitcast <8 x i16> [[SHL10]] to <16 x i8> -; CHECK-NEXT: [[ADD12:%.*]] = add <16 x i8> [[BITCAST11]], [[BITCAST7]] -; CHECK-NEXT: [[ADD13:%.*]] = add <16 x i8> [[ADD12]], [[BITCAST3]] -; CHECK-NEXT: ret <16 x i8> [[ADD13]] -; - - %shufflevector = shufflevector <32 x i8> %arg, <32 x i8> poison, <16 x i32> - %shufflevector2 = shufflevector <32 x i8> %arg, <32 x i8> poison, <16 x i32> - %add = add <16 x i8> %shufflevector, %shufflevector2 - %bitcast = bitcast <16 x i8> %add to <8 x i16> - %shl = shl <8 x i16> %bitcast, splat (i16 8) - %bitcast3 = bitcast <8 x i16> %shl to <16 x i8> - %bitcast4 = bitcast <32 x i8> %arg1 to <16 x i16> - %shufflevector5 = shufflevector <16 x i16> %bitcast4, <16 x i16> poison, <8 x i32> - %shl6 = shl <8 x i16> %shufflevector5, splat (i16 8) - %bitcast7 = bitcast <8 x i16> %shl6 to <16 x i8> - %bitcast8 = bitcast <32 x i8> %arg1 to <16 x i16> - %shufflevector9 = shufflevector <16 x i16> %bitcast8, <16 x i16> poison, <8 x i32> - %shl10 = shl <8 x i16> %shufflevector9, splat (i16 8) - %bitcast11 = bitcast <8 x i16> %shl10 to <16 x i8> - %add12 = add <16 x i8> %bitcast11, %bitcast7 - %add13 = add <16 x i8> %add12, %bitcast3 - %bitcast14 = bitcast <16 x i8> %add12 to <8 x i16> - %shl15 = shl <8 x i16> %bitcast14, splat (i16 8) - %bitcast16 = bitcast <8 x i16> %shl15 to <16 x i8> - %add17 = add <16 x i8> %add13, %bitcast16 - ret <16 x i8> %add17 -} - -declare <2 x i64> @llvm.ctpop.v2i64(<2 x i64>) #0 - -declare { i32, i1 } @llvm.uadd.with.overflow.i32(i32, i32) #0 - -attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } From ac66a2a1f549a500e9fb822bc630c5f398d701c9 Mon Sep 17 00:00:00 2001 From: Abhishek Kaushik Date: Wed, 18 Jun 2025 22:51:02 +0530 Subject: [PATCH 09/10] Update tests --- .../InstCombine/bitcast-known-bits.ll | 238 +++--------------- 1 file changed, 41 insertions(+), 197 deletions(-) diff --git a/llvm/test/Transforms/InstCombine/bitcast-known-bits.ll b/llvm/test/Transforms/InstCombine/bitcast-known-bits.ll index ae25b11c59943..826df732d13bc 100644 --- a/llvm/test/Transforms/InstCombine/bitcast-known-bits.ll +++ b/llvm/test/Transforms/InstCombine/bitcast-known-bits.ll @@ -4,6 +4,7 @@ ; PR125228 define <16 x i8> @knownbits_bitcast_masked_shift(<16 x i8> %arg1, <16 x i8> %arg2) { +<<<<<<< HEAD ; CHECK-LABEL: define <16 x i8> @knownbits_bitcast_masked_shift( ; CHECK-SAME: <16 x i8> [[ARG1:%.*]], <16 x i8> [[ARG2:%.*]]) { ; CHECK-NEXT: [[AND:%.*]] = and <16 x i8> [[ARG1]], splat (i8 3) @@ -139,84 +140,39 @@ declare { i32, i1 } @llvm.uadd.with.overflow.i32(i32, i32) ; PR125228 define <16 x i8> @knownbits_bitcast_masked_shift(<16 x i8> %arg) { +======= +>>>>>>> 46898bd99c8b (Update tests) ; CHECK-LABEL: define <16 x i8> @knownbits_bitcast_masked_shift( -; CHECK-SAME: <16 x i8> [[ARG:%.*]]) { -; CHECK-NEXT: [[BITCAST:%.*]] = bitcast <16 x i8> [[ARG]] to <8 x i16> -; CHECK-NEXT: [[LSHR:%.*]] = lshr <8 x i16> [[BITCAST]], splat (i16 4) -; CHECK-NEXT: [[BITCAST1:%.*]] = bitcast <8 x i16> [[LSHR]] to <16 x i8> -; CHECK-NEXT: [[AND:%.*]] = and <16 x i8> [[BITCAST1]], splat (i8 3) -; CHECK-NEXT: [[SHL:%.*]] = shl <8 x i16> [[BITCAST]], splat (i16 4) -; CHECK-NEXT: [[BITCAST2:%.*]] = bitcast <8 x i16> [[SHL]] to <16 x i8> -; CHECK-NEXT: [[AND3:%.*]] = and <16 x i8> [[BITCAST2]], splat (i8 48) -; CHECK-NEXT: [[OR:%.*]] = or disjoint <16 x i8> [[AND]], [[AND3]] +; CHECK-SAME: <16 x i8> [[ARG1:%.*]], <16 x i8> [[ARG2:%.*]]) { +; CHECK-NEXT: [[AND:%.*]] = and <16 x i8> [[ARG1]], splat (i8 3) +; CHECK-NEXT: [[AND3:%.*]] = and <16 x i8> [[ARG2]], splat (i8 48) +; CHECK-NEXT: [[OR:%.*]] = or disjoint <16 x i8> [[AND3]], [[AND]] ; CHECK-NEXT: [[BITCAST4:%.*]] = bitcast <16 x i8> [[OR]] to <8 x i16> ; CHECK-NEXT: [[SHL5:%.*]] = shl nuw <8 x i16> [[BITCAST4]], splat (i16 2) ; CHECK-NEXT: [[BITCAST6:%.*]] = bitcast <8 x i16> [[SHL5]] to <16 x i8> ; CHECK-NEXT: ret <16 x i8> [[BITCAST6]] ; - %bitcast = bitcast <16 x i8> %arg to <8 x i16> - %lshr = lshr <8 x i16> %bitcast, splat (i16 4) - %bitcast1 = bitcast <8 x i16> %lshr to <16 x i8> - %and = and <16 x i8> %bitcast1, splat (i8 3) - %shl = shl <8 x i16> %bitcast, splat (i16 4) - %bitcast2 = bitcast <8 x i16> %shl to <16 x i8> - %and3 = and <16 x i8> %bitcast2, splat (i8 48) - %or = or disjoint <16 x i8> %and, %and3 + %and = and <16 x i8> %arg1, splat (i8 3) + %and3 = and <16 x i8> %arg2, splat (i8 48) + %or = or disjoint <16 x i8> %and3, %and %bitcast4 = bitcast <16 x i8> %or to <8 x i16> %shl5 = shl nuw <8 x i16> %bitcast4, splat (i16 2) %bitcast6 = bitcast <8 x i16> %shl5 to <16 x i8> - %and7 = and <16 x i8> %bitcast6, splat (i8 -4) + %and7 = and <16 x i8> %bitcast6, splat (i8 -52) ret <16 x i8> %and7 } -define <16 x i8> @knownbits_shuffle_bitcast_masked_shift(<8 x i16> %arg) { -; CHECK-LABEL: define <16 x i8> @knownbits_shuffle_bitcast_masked_shift( -; CHECK-SAME: <8 x i16> [[ARG:%.*]]) { -; CHECK-NEXT: [[BITCAST:%.*]] = bitcast <8 x i16> [[ARG]] to <16 x i8> -; CHECK-NEXT: [[SHUFFLEVECTOR:%.*]] = shufflevector <16 x i8> [[BITCAST]], <16 x i8> poison, <16 x i32> -; CHECK-NEXT: [[BITCAST1:%.*]] = bitcast <16 x i8> [[SHUFFLEVECTOR]] to <8 x i16> -; CHECK-NEXT: [[LSHR:%.*]] = lshr <8 x i16> [[BITCAST1]], splat (i16 4) -; CHECK-NEXT: [[BITCAST2:%.*]] = bitcast <8 x i16> [[LSHR]] to <16 x i8> -; CHECK-NEXT: [[AND:%.*]] = and <16 x i8> [[BITCAST2]], splat (i8 3) -; CHECK-NEXT: [[SHL:%.*]] = shl <8 x i16> [[BITCAST1]], splat (i16 4) -; CHECK-NEXT: [[BITCAST3:%.*]] = bitcast <8 x i16> [[SHL]] to <16 x i8> -; CHECK-NEXT: [[AND4:%.*]] = and <16 x i8> [[BITCAST3]], splat (i8 48) -; CHECK-NEXT: [[OR:%.*]] = or disjoint <16 x i8> [[AND]], [[AND4]] -; CHECK-NEXT: [[BITCAST5:%.*]] = bitcast <16 x i8> [[OR]] to <8 x i16> -; CHECK-NEXT: [[SHL6:%.*]] = shl nuw <8 x i16> [[BITCAST5]], splat (i16 2) -; CHECK-NEXT: [[BITCAST7:%.*]] = bitcast <8 x i16> [[SHL6]] to <16 x i8> -; CHECK-NEXT: ret <16 x i8> [[BITCAST7]] -; - %bitcast = bitcast <8 x i16> %arg to <16 x i8> - %shufflevector = shufflevector <16 x i8> %bitcast, <16 x i8> poison, <16 x i32> - %bitcast1 = bitcast <16 x i8> %shufflevector to <8 x i16> - %lshr = lshr <8 x i16> %bitcast1, splat (i16 4) - %bitcast2 = bitcast <8 x i16> %lshr to <16 x i8> - %and = and <16 x i8> %bitcast2, splat (i8 3) - %shl = shl <8 x i16> %bitcast1, splat (i16 4) - %bitcast3 = bitcast <8 x i16> %shl to <16 x i8> - %and4 = and <16 x i8> %bitcast3, splat (i8 48) - %or = or disjoint <16 x i8> %and, %and4 - %bitcast5 = bitcast <16 x i8> %or to <8 x i16> - %shl6 = shl nuw <8 x i16> %bitcast5, splat (i16 2) - %bitcast7 = bitcast <8 x i16> %shl6 to <16 x i8> - %and8 = and <16 x i8> %bitcast7, splat (i8 -4) - ret <16 x i8> %and8 -} - -define <16 x i8> @knownbits_shuffle_masked_nibble_shift(<8 x i16> %arg) { +define <16 x i8> @knownbits_shuffle_masked_nibble_shift(<16 x i8> %arg) { ; CHECK-LABEL: define <16 x i8> @knownbits_shuffle_masked_nibble_shift( -; CHECK-SAME: <8 x i16> [[ARG:%.*]]) { -; CHECK-NEXT: [[BITCAST:%.*]] = bitcast <8 x i16> [[ARG]] to <16 x i8> -; CHECK-NEXT: [[AND:%.*]] = and <16 x i8> [[BITCAST]], splat (i8 15) +; CHECK-SAME: <16 x i8> [[ARG:%.*]]) { +; CHECK-NEXT: [[AND:%.*]] = and <16 x i8> [[ARG]], splat (i8 15) ; CHECK-NEXT: [[SHUFFLEVECTOR:%.*]] = shufflevector <16 x i8> [[AND]], <16 x i8> poison, <16 x i32> ; CHECK-NEXT: [[BITCAST1:%.*]] = bitcast <16 x i8> [[SHUFFLEVECTOR]] to <8 x i16> ; CHECK-NEXT: [[SHL:%.*]] = shl nuw <8 x i16> [[BITCAST1]], splat (i16 4) ; CHECK-NEXT: [[BITCAST2:%.*]] = bitcast <8 x i16> [[SHL]] to <16 x i8> ; CHECK-NEXT: ret <16 x i8> [[BITCAST2]] ; - %bitcast = bitcast <8 x i16> %arg to <16 x i8> - %and = and <16 x i8> %bitcast, splat (i8 15) + %and = and <16 x i8> %arg, splat (i8 15) %shufflevector = shufflevector <16 x i8> %and, <16 x i8> poison, <16 x i32> %bitcast1 = bitcast <16 x i8> %shufflevector to <8 x i16> %shl = shl nuw <8 x i16> %bitcast1, splat (i16 4) @@ -225,19 +181,17 @@ define <16 x i8> @knownbits_shuffle_masked_nibble_shift(<8 x i16> %arg) { ret <16 x i8> %and3 } -define <16 x i8> @knownbits_reverse_shuffle_masked_shift(<8 x i16> %arg) { +define <16 x i8> @knownbits_reverse_shuffle_masked_shift(<16 x i8> %arg) { ; CHECK-LABEL: define <16 x i8> @knownbits_reverse_shuffle_masked_shift( -; CHECK-SAME: <8 x i16> [[ARG:%.*]]) { -; CHECK-NEXT: [[BITCAST:%.*]] = bitcast <8 x i16> [[ARG]] to <16 x i8> -; CHECK-NEXT: [[AND:%.*]] = and <16 x i8> [[BITCAST]], splat (i8 15) +; CHECK-SAME: <16 x i8> [[ARG:%.*]]) { +; CHECK-NEXT: [[AND:%.*]] = and <16 x i8> [[ARG]], splat (i8 15) ; CHECK-NEXT: [[SHUFFLEVECTOR:%.*]] = shufflevector <16 x i8> [[AND]], <16 x i8> poison, <16 x i32> ; CHECK-NEXT: [[BITCAST1:%.*]] = bitcast <16 x i8> [[SHUFFLEVECTOR]] to <8 x i16> ; CHECK-NEXT: [[SHL:%.*]] = shl nuw <8 x i16> [[BITCAST1]], splat (i16 4) ; CHECK-NEXT: [[BITCAST2:%.*]] = bitcast <8 x i16> [[SHL]] to <16 x i8> ; CHECK-NEXT: ret <16 x i8> [[BITCAST2]] ; - %bitcast = bitcast <8 x i16> %arg to <16 x i8> - %and = and <16 x i8> %bitcast, splat (i8 15) + %and = and <16 x i8> %arg, splat (i8 15) %shufflevector = shufflevector <16 x i8> %and, <16 x i8> poison, <16 x i32> %bitcast1 = bitcast <16 x i8> %shufflevector to <8 x i16> %shl = shl nuw <8 x i16> %bitcast1, splat (i16 4) @@ -246,167 +200,59 @@ define <16 x i8> @knownbits_reverse_shuffle_masked_shift(<8 x i16> %arg) { ret <16 x i8> %and3 } -define <16 x i8> @knownbits_interleave_mul_extract_bit(<16 x i8> %arg) { -; CHECK-LABEL: define <16 x i8> @knownbits_interleave_mul_extract_bit( -; CHECK-SAME: <16 x i8> [[ARG:%.*]]) { -; CHECK-NEXT: [[SHUFFLEVECTOR:%.*]] = shufflevector <16 x i8> [[ARG]], <16 x i8> , <16 x i32> -; CHECK-NEXT: [[BITCAST:%.*]] = bitcast <16 x i8> [[SHUFFLEVECTOR]] to <8 x i16> -; CHECK-NEXT: [[MUL:%.*]] = mul nuw <8 x i16> [[BITCAST]], -; CHECK-NEXT: [[LSHR:%.*]] = lshr <8 x i16> [[MUL]], splat (i16 15) +define <16 x i8> @knownbits_extract_bit(<8 x i16> %arg) { +; CHECK-LABEL: define <16 x i8> @knownbits_extract_bit( +; CHECK-SAME: <8 x i16> [[ARG:%.*]]) { +; CHECK-NEXT: [[LSHR:%.*]] = lshr <8 x i16> [[ARG]], splat (i16 15) ; CHECK-NEXT: [[BITCAST1:%.*]] = bitcast <8 x i16> [[LSHR]] to <16 x i8> ; CHECK-NEXT: ret <16 x i8> [[BITCAST1]] ; - %shufflevector = shufflevector <16 x i8> %arg, <16 x i8> , <16 x i32> - %bitcast = bitcast <16 x i8> %shufflevector to <8 x i16> - %mul = mul nuw <8 x i16> %bitcast, - %lshr = lshr <8 x i16> %mul, splat (i16 15) + %lshr = lshr <8 x i16> %arg, splat (i16 15) %bitcast1 = bitcast <8 x i16> %lshr to <16 x i8> %and = and <16 x i8> %bitcast1, splat (i8 1) ret <16 x i8> %and } -define <16 x i8> @knownbits_reverse_shuffle_masked_ops(<8 x i16> %arg) { -; CHECK-LABEL: define <16 x i8> @knownbits_reverse_shuffle_masked_ops( -; CHECK-SAME: <8 x i16> [[ARG:%.*]]) { -; CHECK-NEXT: [[BITCAST:%.*]] = bitcast <8 x i16> [[ARG]] to <16 x i8> -; CHECK-NEXT: [[SHUFFLEVECTOR:%.*]] = shufflevector <16 x i8> [[BITCAST]], <16 x i8> poison, <16 x i32> -; CHECK-NEXT: [[BITCAST1:%.*]] = bitcast <16 x i8> [[SHUFFLEVECTOR]] to <8 x i16> -; CHECK-NEXT: [[LSHR:%.*]] = lshr <8 x i16> [[BITCAST1]], splat (i16 4) -; CHECK-NEXT: [[BITCAST2:%.*]] = bitcast <8 x i16> [[LSHR]] to <16 x i8> -; CHECK-NEXT: [[AND:%.*]] = and <16 x i8> [[BITCAST2]], splat (i8 3) -; CHECK-NEXT: [[SHL:%.*]] = shl <8 x i16> [[BITCAST1]], splat (i16 4) -; CHECK-NEXT: [[BITCAST3:%.*]] = bitcast <8 x i16> [[SHL]] to <16 x i8> -; CHECK-NEXT: [[AND4:%.*]] = and <16 x i8> [[BITCAST3]], splat (i8 48) -; CHECK-NEXT: [[OR:%.*]] = or disjoint <16 x i8> [[AND]], [[AND4]] -; CHECK-NEXT: [[BITCAST5:%.*]] = bitcast <16 x i8> [[OR]] to <8 x i16> -; CHECK-NEXT: [[SHL6:%.*]] = shl nuw <8 x i16> [[BITCAST5]], splat (i16 2) -; CHECK-NEXT: [[BITCAST7:%.*]] = bitcast <8 x i16> [[SHL6]] to <16 x i8> -; CHECK-NEXT: ret <16 x i8> [[BITCAST7]] -; - %bitcast = bitcast <8 x i16> %arg to <16 x i8> - %shufflevector = shufflevector <16 x i8> %bitcast, <16 x i8> poison, <16 x i32> - %bitcast1 = bitcast <16 x i8> %shufflevector to <8 x i16> - %lshr = lshr <8 x i16> %bitcast1, splat (i16 4) - %bitcast2 = bitcast <8 x i16> %lshr to <16 x i8> - %and = and <16 x i8> %bitcast2, splat (i8 3) - %shl = shl <8 x i16> %bitcast1, splat (i16 4) - %bitcast3 = bitcast <8 x i16> %shl to <16 x i8> - %and4 = and <16 x i8> %bitcast3, splat (i8 48) - %or = or disjoint <16 x i8> %and, %and4 - %bitcast5 = bitcast <16 x i8> %or to <8 x i16> - %shl6 = shl nuw <8 x i16> %bitcast5, splat (i16 2) - %bitcast7 = bitcast <8 x i16> %shl6 to <16 x i8> - %and8 = and <16 x i8> %bitcast7, splat (i8 -4) - ret <16 x i8> %and8 -} - -define <16 x i8> @knownbits_v4i32_to_v16i8_shuffle_masked_pipeline(<4 x i32> %arg) { -; CHECK-LABEL: define <16 x i8> @knownbits_v4i32_to_v16i8_shuffle_masked_pipeline( -; CHECK-SAME: <4 x i32> [[ARG:%.*]]) { -; CHECK-NEXT: [[BITCAST:%.*]] = bitcast <4 x i32> [[ARG]] to <16 x i8> -; CHECK-NEXT: [[SHUFFLEVECTOR:%.*]] = shufflevector <16 x i8> [[BITCAST]], <16 x i8> poison, <16 x i32> -; CHECK-NEXT: [[BITCAST1:%.*]] = bitcast <16 x i8> [[SHUFFLEVECTOR]] to <8 x i16> -; CHECK-NEXT: [[SHL:%.*]] = shl <8 x i16> [[BITCAST1]], splat (i16 4) -; CHECK-NEXT: [[BITCAST2:%.*]] = bitcast <8 x i16> [[SHL]] to <16 x i8> -; CHECK-NEXT: [[AND:%.*]] = and <16 x i8> [[BITCAST2]], splat (i8 48) -; CHECK-NEXT: [[LSHR:%.*]] = lshr <8 x i16> [[BITCAST1]], splat (i16 4) -; CHECK-NEXT: [[BITCAST3:%.*]] = bitcast <8 x i16> [[LSHR]] to <16 x i8> -; CHECK-NEXT: [[AND4:%.*]] = and <16 x i8> [[BITCAST3]], splat (i8 3) -; CHECK-NEXT: [[OR:%.*]] = or disjoint <16 x i8> [[AND4]], [[AND]] -; CHECK-NEXT: [[BITCAST5:%.*]] = bitcast <16 x i8> [[OR]] to <8 x i16> -; CHECK-NEXT: [[SHL6:%.*]] = shl nuw <8 x i16> [[BITCAST5]], splat (i16 2) -; CHECK-NEXT: [[BITCAST7:%.*]] = bitcast <8 x i16> [[SHL6]] to <16 x i8> -; CHECK-NEXT: ret <16 x i8> [[BITCAST7]] -; - %bitcast = bitcast <4 x i32> %arg to <16 x i8> - %shufflevector = shufflevector <16 x i8> %bitcast, <16 x i8> poison, <16 x i32> - %bitcast1 = bitcast <16 x i8> %shufflevector to <8 x i16> - %shl = shl <8 x i16> %bitcast1, splat (i16 4) - %bitcast2 = bitcast <8 x i16> %shl to <16 x i8> - %and = and <16 x i8> %bitcast2, splat (i8 48) - %lshr = lshr <8 x i16> %bitcast1, splat (i16 4) - %bitcast3 = bitcast <8 x i16> %lshr to <16 x i8> - %and4 = and <16 x i8> %bitcast3, splat (i8 3) - %or = or disjoint <16 x i8> %and4, %and - %bitcast5 = bitcast <16 x i8> %or to <8 x i16> - %shl6 = shl nuw <8 x i16> %bitcast5, splat (i16 2) - %bitcast7 = bitcast <8 x i16> %shl6 to <16 x i8> - %and8 = and <16 x i8> %bitcast7, splat (i8 -4) - ret <16 x i8> %and8 -} - -define { i32, i1 } @knownbits_popcount_add_with_overflow(i32 %arg, i32 %arg1, i32 %arg2, i32 %arg3) { +define { i32, i1 } @knownbits_popcount_add_with_overflow(<2 x i64> %arg1, <2 x i64> %arg2) { ; CHECK-LABEL: define { i32, i1 } @knownbits_popcount_add_with_overflow( -; CHECK-SAME: i32 [[ARG:%.*]], i32 [[ARG1:%.*]], i32 [[ARG2:%.*]], i32 [[ARG3:%.*]]) { -; CHECK-NEXT: [[INSERTELEMENT:%.*]] = insertelement <4 x i32> poison, i32 [[ARG2]], i64 0 -; CHECK-NEXT: [[INSERTELEMENT4:%.*]] = insertelement <4 x i32> [[INSERTELEMENT]], i32 [[ARG3]], i64 1 -; CHECK-NEXT: [[BITCAST:%.*]] = bitcast <4 x i32> [[INSERTELEMENT4]] to <2 x i64> -; CHECK-NEXT: [[CALL:%.*]] = tail call range(i64 0, 65) <2 x i64> @llvm.ctpop.v2i64(<2 x i64> [[BITCAST]]) +; CHECK-SAME: <2 x i64> [[ARG1:%.*]], <2 x i64> [[ARG2:%.*]]) { +; CHECK-NEXT: [[CALL:%.*]] = tail call range(i64 0, 65) <2 x i64> @llvm.ctpop.v2i64(<2 x i64> [[ARG1]]) ; CHECK-NEXT: [[BITCAST5:%.*]] = bitcast <2 x i64> [[CALL]] to <4 x i32> ; CHECK-NEXT: [[EXTRACTELEMENT:%.*]] = extractelement <4 x i32> [[BITCAST5]], i64 0 -; CHECK-NEXT: [[INSERTELEMENT6:%.*]] = insertelement <4 x i32> poison, i32 [[ARG]], i64 0 -; CHECK-NEXT: [[INSERTELEMENT7:%.*]] = insertelement <4 x i32> [[INSERTELEMENT6]], i32 [[ARG1]], i64 1 -; CHECK-NEXT: [[BITCAST8:%.*]] = bitcast <4 x i32> [[INSERTELEMENT7]] to <2 x i64> -; CHECK-NEXT: [[CALL9:%.*]] = tail call range(i64 0, 65) <2 x i64> @llvm.ctpop.v2i64(<2 x i64> [[BITCAST8]]) +; CHECK-NEXT: [[CALL9:%.*]] = tail call range(i64 0, 65) <2 x i64> @llvm.ctpop.v2i64(<2 x i64> [[ARG2]]) ; CHECK-NEXT: [[BITCAST10:%.*]] = bitcast <2 x i64> [[CALL9]] to <4 x i32> ; CHECK-NEXT: [[EXTRACTELEMENT11:%.*]] = extractelement <4 x i32> [[BITCAST10]], i64 0 ; CHECK-NEXT: [[CALL12:%.*]] = add nuw nsw i32 [[EXTRACTELEMENT]], [[EXTRACTELEMENT11]] ; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { i32, i1 } { i32 poison, i1 false }, i32 [[CALL12]], 0 ; CHECK-NEXT: ret { i32, i1 } [[TMP1]] ; - %insertelement = insertelement <4 x i32> poison, i32 %arg2, i64 0 - %insertelement4 = insertelement <4 x i32> %insertelement, i32 %arg3, i64 1 - %bitcast = bitcast <4 x i32> %insertelement4 to <2 x i64> - %call = tail call <2 x i64> @llvm.ctpop.v2i64(<2 x i64> %bitcast) + %call = tail call <2 x i64> @llvm.ctpop.v2i64(<2 x i64> %arg1) %bitcast5 = bitcast <2 x i64> %call to <4 x i32> %extractelement = extractelement <4 x i32> %bitcast5, i64 0 - %insertelement6 = insertelement <4 x i32> poison, i32 %arg, i64 0 - %insertelement7 = insertelement <4 x i32> %insertelement6, i32 %arg1, i64 1 - %bitcast8 = bitcast <4 x i32> %insertelement7 to <2 x i64> - %call9 = tail call <2 x i64> @llvm.ctpop.v2i64(<2 x i64> %bitcast8) + %call9 = tail call <2 x i64> @llvm.ctpop.v2i64(<2 x i64> %arg2) %bitcast10 = bitcast <2 x i64> %call9 to <4 x i32> %extractelement11 = extractelement <4 x i32> %bitcast10, i64 0 %call12 = tail call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %extractelement, i32 %extractelement11) ret { i32, i1 } %call12 } -define <16 x i8> @knownbits_shuffle_add_shift_v32i8(<32 x i8> %arg, <32 x i8> %arg1) local_unnamed_addr #0 { +define <16 x i8> @knownbits_shuffle_add_shift_v32i8(<16 x i8> %arg1, <8 x i16> %arg2, <8 x i16> %arg3) { ; CHECK-LABEL: define <16 x i8> @knownbits_shuffle_add_shift_v32i8( -; CHECK-SAME: <32 x i8> [[ARG:%.*]], <32 x i8> [[ARG1:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { -; CHECK-NEXT: [[SHUFFLEVECTOR:%.*]] = shufflevector <32 x i8> [[ARG]], <32 x i8> poison, <16 x i32> -; CHECK-NEXT: [[SHUFFLEVECTOR2:%.*]] = shufflevector <32 x i8> [[ARG]], <32 x i8> poison, <16 x i32> -; CHECK-NEXT: [[ADD:%.*]] = add <16 x i8> [[SHUFFLEVECTOR]], [[SHUFFLEVECTOR2]] -; CHECK-NEXT: [[BITCAST:%.*]] = bitcast <16 x i8> [[ADD]] to <8 x i16> -; CHECK-NEXT: [[SHL:%.*]] = shl <8 x i16> [[BITCAST]], splat (i16 8) -; CHECK-NEXT: [[BITCAST3:%.*]] = bitcast <8 x i16> [[SHL]] to <16 x i8> -; CHECK-NEXT: [[BITCAST4:%.*]] = bitcast <32 x i8> [[ARG1]] to <16 x i16> -; CHECK-NEXT: [[SHUFFLEVECTOR5:%.*]] = shufflevector <16 x i16> [[BITCAST4]], <16 x i16> poison, <8 x i32> -; CHECK-NEXT: [[SHL6:%.*]] = shl <8 x i16> [[SHUFFLEVECTOR5]], splat (i16 8) +; CHECK-SAME: <16 x i8> [[ARG1:%.*]], <8 x i16> [[ARG2:%.*]], <8 x i16> [[ARG3:%.*]]) { +; CHECK-NEXT: [[SHL6:%.*]] = shl <8 x i16> [[ARG2]], splat (i16 8) ; CHECK-NEXT: [[BITCAST7:%.*]] = bitcast <8 x i16> [[SHL6]] to <16 x i8> -; CHECK-NEXT: [[BITCAST8:%.*]] = bitcast <32 x i8> [[ARG1]] to <16 x i16> -; CHECK-NEXT: [[SHUFFLEVECTOR9:%.*]] = shufflevector <16 x i16> [[BITCAST8]], <16 x i16> poison, <8 x i32> -; CHECK-NEXT: [[SHL10:%.*]] = shl <8 x i16> [[SHUFFLEVECTOR9]], splat (i16 8) +; CHECK-NEXT: [[SHL10:%.*]] = shl <8 x i16> [[ARG3]], splat (i16 8) ; CHECK-NEXT: [[BITCAST11:%.*]] = bitcast <8 x i16> [[SHL10]] to <16 x i8> ; CHECK-NEXT: [[ADD12:%.*]] = add <16 x i8> [[BITCAST11]], [[BITCAST7]] -; CHECK-NEXT: [[ADD17:%.*]] = add <16 x i8> [[ADD12]], [[BITCAST3]] -; CHECK-NEXT: ret <16 x i8> [[ADD17]] +; CHECK-NEXT: [[ADD14:%.*]] = add <16 x i8> [[ADD12]], [[ARG1]] +; CHECK-NEXT: ret <16 x i8> [[ADD14]] ; - %shufflevector = shufflevector <32 x i8> %arg, <32 x i8> poison, <16 x i32> - %shufflevector2 = shufflevector <32 x i8> %arg, <32 x i8> poison, <16 x i32> - %add = add <16 x i8> %shufflevector, %shufflevector2 - %bitcast = bitcast <16 x i8> %add to <8 x i16> - %shl = shl <8 x i16> %bitcast, splat (i16 8) - %bitcast3 = bitcast <8 x i16> %shl to <16 x i8> - %bitcast4 = bitcast <32 x i8> %arg1 to <16 x i16> - %shufflevector5 = shufflevector <16 x i16> %bitcast4, <16 x i16> poison, <8 x i32> - %shl6 = shl <8 x i16> %shufflevector5, splat (i16 8) + %shl6 = shl <8 x i16> %arg2, splat (i16 8) %bitcast7 = bitcast <8 x i16> %shl6 to <16 x i8> - %bitcast8 = bitcast <32 x i8> %arg1 to <16 x i16> - %shufflevector9 = shufflevector <16 x i16> %bitcast8, <16 x i16> poison, <8 x i32> - %shl10 = shl <8 x i16> %shufflevector9, splat (i16 8) + %shl10 = shl <8 x i16> %arg3, splat (i16 8) %bitcast11 = bitcast <8 x i16> %shl10 to <16 x i8> %add12 = add <16 x i8> %bitcast11, %bitcast7 - %add13 = add <16 x i8> %add12, %bitcast3 + %add13 = add <16 x i8> %add12, %arg1 %bitcast14 = bitcast <16 x i8> %add12 to <8 x i16> %shl15 = shl <8 x i16> %bitcast14, splat (i16 8) %bitcast16 = bitcast <8 x i16> %shl15 to <16 x i8> @@ -414,8 +260,6 @@ define <16 x i8> @knownbits_shuffle_add_shift_v32i8(<32 x i8> %arg, <32 x i8> %a ret <16 x i8> %add17 } -declare <2 x i64> @llvm.ctpop.v2i64(<2 x i64>) #0 - -declare { i32, i1 } @llvm.uadd.with.overflow.i32(i32, i32) #0 +declare <2 x i64> @llvm.ctpop.v2i64(<2 x i64>) -attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } +declare { i32, i1 } @llvm.uadd.with.overflow.i32(i32, i32) From 801b08d6380ed0fa99d8fcaa989ed470db27d3eb Mon Sep 17 00:00:00 2001 From: Abhishek Kaushik Date: Thu, 19 Jun 2025 21:46:57 +0530 Subject: [PATCH 10/10] Update bitcast-known-bits.ll --- .../InstCombine/bitcast-known-bits.ll | 138 ------------------ 1 file changed, 138 deletions(-) diff --git a/llvm/test/Transforms/InstCombine/bitcast-known-bits.ll b/llvm/test/Transforms/InstCombine/bitcast-known-bits.ll index 826df732d13bc..65b43df752f76 100644 --- a/llvm/test/Transforms/InstCombine/bitcast-known-bits.ll +++ b/llvm/test/Transforms/InstCombine/bitcast-known-bits.ll @@ -4,144 +4,6 @@ ; PR125228 define <16 x i8> @knownbits_bitcast_masked_shift(<16 x i8> %arg1, <16 x i8> %arg2) { -<<<<<<< HEAD -; CHECK-LABEL: define <16 x i8> @knownbits_bitcast_masked_shift( -; CHECK-SAME: <16 x i8> [[ARG1:%.*]], <16 x i8> [[ARG2:%.*]]) { -; CHECK-NEXT: [[AND:%.*]] = and <16 x i8> [[ARG1]], splat (i8 3) -; CHECK-NEXT: [[AND3:%.*]] = and <16 x i8> [[ARG2]], splat (i8 48) -; CHECK-NEXT: [[OR:%.*]] = or disjoint <16 x i8> [[AND3]], [[AND]] -; CHECK-NEXT: [[BITCAST4:%.*]] = bitcast <16 x i8> [[OR]] to <8 x i16> -; CHECK-NEXT: [[SHL5:%.*]] = shl nuw <8 x i16> [[BITCAST4]], splat (i16 2) -; CHECK-NEXT: [[BITCAST6:%.*]] = bitcast <8 x i16> [[SHL5]] to <16 x i8> -; CHECK-NEXT: [[AND7:%.*]] = and <16 x i8> [[BITCAST6]], splat (i8 -52) -; CHECK-NEXT: ret <16 x i8> [[AND7]] -; - %and = and <16 x i8> %arg1, splat (i8 3) - %and3 = and <16 x i8> %arg2, splat (i8 48) - %or = or disjoint <16 x i8> %and3, %and - %bitcast4 = bitcast <16 x i8> %or to <8 x i16> - %shl5 = shl nuw <8 x i16> %bitcast4, splat (i16 2) - %bitcast6 = bitcast <8 x i16> %shl5 to <16 x i8> - %and7 = and <16 x i8> %bitcast6, splat (i8 -52) - ret <16 x i8> %and7 -} - -define <16 x i8> @knownbits_shuffle_masked_nibble_shift(<16 x i8> %arg) { -; CHECK-LABEL: define <16 x i8> @knownbits_shuffle_masked_nibble_shift( -; CHECK-SAME: <16 x i8> [[ARG:%.*]]) { -; CHECK-NEXT: [[AND:%.*]] = and <16 x i8> [[ARG]], splat (i8 15) -; CHECK-NEXT: [[SHUFFLEVECTOR:%.*]] = shufflevector <16 x i8> [[AND]], <16 x i8> poison, <16 x i32> -; CHECK-NEXT: [[BITCAST1:%.*]] = bitcast <16 x i8> [[SHUFFLEVECTOR]] to <8 x i16> -; CHECK-NEXT: [[SHL:%.*]] = shl nuw <8 x i16> [[BITCAST1]], splat (i16 4) -; CHECK-NEXT: [[BITCAST2:%.*]] = bitcast <8 x i16> [[SHL]] to <16 x i8> -; CHECK-NEXT: [[AND3:%.*]] = and <16 x i8> [[BITCAST2]], splat (i8 -16) -; CHECK-NEXT: ret <16 x i8> [[AND3]] -; - %and = and <16 x i8> %arg, splat (i8 15) - %shufflevector = shufflevector <16 x i8> %and, <16 x i8> poison, <16 x i32> - %bitcast1 = bitcast <16 x i8> %shufflevector to <8 x i16> - %shl = shl nuw <8 x i16> %bitcast1, splat (i16 4) - %bitcast2 = bitcast <8 x i16> %shl to <16 x i8> - %and3 = and <16 x i8> %bitcast2, splat (i8 -16) - ret <16 x i8> %and3 -} - -define <16 x i8> @knownbits_reverse_shuffle_masked_shift(<16 x i8> %arg) { -; CHECK-LABEL: define <16 x i8> @knownbits_reverse_shuffle_masked_shift( -; CHECK-SAME: <16 x i8> [[ARG:%.*]]) { -; CHECK-NEXT: [[AND:%.*]] = and <16 x i8> [[ARG]], splat (i8 15) -; CHECK-NEXT: [[SHUFFLEVECTOR:%.*]] = shufflevector <16 x i8> [[AND]], <16 x i8> poison, <16 x i32> -; CHECK-NEXT: [[BITCAST1:%.*]] = bitcast <16 x i8> [[SHUFFLEVECTOR]] to <8 x i16> -; CHECK-NEXT: [[SHL:%.*]] = shl nuw <8 x i16> [[BITCAST1]], splat (i16 4) -; CHECK-NEXT: [[BITCAST2:%.*]] = bitcast <8 x i16> [[SHL]] to <16 x i8> -; CHECK-NEXT: [[AND3:%.*]] = and <16 x i8> [[BITCAST2]], splat (i8 -16) -; CHECK-NEXT: ret <16 x i8> [[AND3]] -; - %and = and <16 x i8> %arg, splat (i8 15) - %shufflevector = shufflevector <16 x i8> %and, <16 x i8> poison, <16 x i32> - %bitcast1 = bitcast <16 x i8> %shufflevector to <8 x i16> - %shl = shl nuw <8 x i16> %bitcast1, splat (i16 4) - %bitcast2 = bitcast <8 x i16> %shl to <16 x i8> - %and3 = and <16 x i8> %bitcast2, splat (i8 -16) - ret <16 x i8> %and3 -} - -define <16 x i8> @knownbits_extract_bit(<8 x i16> %arg) { -; CHECK-LABEL: define <16 x i8> @knownbits_extract_bit( -; CHECK-SAME: <8 x i16> [[ARG:%.*]]) { -; CHECK-NEXT: [[LSHR:%.*]] = lshr <8 x i16> [[ARG]], splat (i16 15) -; CHECK-NEXT: [[BITCAST1:%.*]] = bitcast <8 x i16> [[LSHR]] to <16 x i8> -; CHECK-NEXT: [[AND:%.*]] = and <16 x i8> [[BITCAST1]], splat (i8 1) -; CHECK-NEXT: ret <16 x i8> [[AND]] -; - %lshr = lshr <8 x i16> %arg, splat (i16 15) - %bitcast1 = bitcast <8 x i16> %lshr to <16 x i8> - %and = and <16 x i8> %bitcast1, splat (i8 1) - ret <16 x i8> %and -} - -define { i32, i1 } @knownbits_popcount_add_with_overflow(<2 x i64> %arg1, <2 x i64> %arg2) { -; CHECK-LABEL: define { i32, i1 } @knownbits_popcount_add_with_overflow( -; CHECK-SAME: <2 x i64> [[ARG1:%.*]], <2 x i64> [[ARG2:%.*]]) { -; CHECK-NEXT: [[CALL:%.*]] = tail call range(i64 0, 65) <2 x i64> @llvm.ctpop.v2i64(<2 x i64> [[ARG1]]) -; CHECK-NEXT: [[BITCAST5:%.*]] = bitcast <2 x i64> [[CALL]] to <4 x i32> -; CHECK-NEXT: [[EXTRACTELEMENT:%.*]] = extractelement <4 x i32> [[BITCAST5]], i64 0 -; CHECK-NEXT: [[CALL9:%.*]] = tail call range(i64 0, 65) <2 x i64> @llvm.ctpop.v2i64(<2 x i64> [[ARG2]]) -; CHECK-NEXT: [[BITCAST10:%.*]] = bitcast <2 x i64> [[CALL9]] to <4 x i32> -; CHECK-NEXT: [[EXTRACTELEMENT11:%.*]] = extractelement <4 x i32> [[BITCAST10]], i64 0 -; CHECK-NEXT: [[TMP1:%.*]] = tail call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[EXTRACTELEMENT]], i32 [[EXTRACTELEMENT11]]) -; CHECK-NEXT: ret { i32, i1 } [[TMP1]] -; - %call = tail call <2 x i64> @llvm.ctpop.v2i64(<2 x i64> %arg1) - %bitcast5 = bitcast <2 x i64> %call to <4 x i32> - %extractelement = extractelement <4 x i32> %bitcast5, i64 0 - %call9 = tail call <2 x i64> @llvm.ctpop.v2i64(<2 x i64> %arg2) - %bitcast10 = bitcast <2 x i64> %call9 to <4 x i32> - %extractelement11 = extractelement <4 x i32> %bitcast10, i64 0 - %call12 = tail call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %extractelement, i32 %extractelement11) - ret { i32, i1 } %call12 -} - -define <16 x i8> @knownbits_shuffle_add_shift_v32i8(<16 x i8> %arg1, <8 x i16> %arg2, <8 x i16> %arg3) { -; CHECK-LABEL: define <16 x i8> @knownbits_shuffle_add_shift_v32i8( -; CHECK-SAME: <16 x i8> [[ARG1:%.*]], <8 x i16> [[ARG2:%.*]], <8 x i16> [[ARG3:%.*]]) { -; CHECK-NEXT: [[SHL6:%.*]] = shl <8 x i16> [[ARG2]], splat (i16 8) -; CHECK-NEXT: [[BITCAST7:%.*]] = bitcast <8 x i16> [[SHL6]] to <16 x i8> -; CHECK-NEXT: [[SHL10:%.*]] = shl <8 x i16> [[ARG3]], splat (i16 8) -; CHECK-NEXT: [[BITCAST11:%.*]] = bitcast <8 x i16> [[SHL10]] to <16 x i8> -; CHECK-NEXT: [[ADD12:%.*]] = add <16 x i8> [[BITCAST11]], [[BITCAST7]] -; CHECK-NEXT: [[ADD14:%.*]] = add <16 x i8> [[ADD12]], [[ARG1]] -; CHECK-NEXT: [[BITCAST14:%.*]] = bitcast <16 x i8> [[ADD12]] to <8 x i16> -; CHECK-NEXT: [[SHL15:%.*]] = shl <8 x i16> [[BITCAST14]], splat (i16 8) -; CHECK-NEXT: [[BITCAST16:%.*]] = bitcast <8 x i16> [[SHL15]] to <16 x i8> -; CHECK-NEXT: [[ADD13:%.*]] = add <16 x i8> [[ADD14]], [[BITCAST16]] -; CHECK-NEXT: ret <16 x i8> [[ADD13]] -; - %shl6 = shl <8 x i16> %arg2, splat (i16 8) - %bitcast7 = bitcast <8 x i16> %shl6 to <16 x i8> - %shl10 = shl <8 x i16> %arg3, splat (i16 8) - %bitcast11 = bitcast <8 x i16> %shl10 to <16 x i8> - %add12 = add <16 x i8> %bitcast11, %bitcast7 - %add13 = add <16 x i8> %add12, %arg1 - %bitcast14 = bitcast <16 x i8> %add12 to <8 x i16> - %shl15 = shl <8 x i16> %bitcast14, splat (i16 8) - %bitcast16 = bitcast <8 x i16> %shl15 to <16 x i8> - %add17 = add <16 x i8> %add13, %bitcast16 - ret <16 x i8> %add17 -} - -declare <2 x i64> @llvm.ctpop.v2i64(<2 x i64>) - -declare { i32, i1 } @llvm.uadd.with.overflow.i32(i32, i32) - -; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 -; RUN: opt < %s -passes=instcombine -S | FileCheck %s - -; PR125228 - -define <16 x i8> @knownbits_bitcast_masked_shift(<16 x i8> %arg) { -======= ->>>>>>> 46898bd99c8b (Update tests) ; CHECK-LABEL: define <16 x i8> @knownbits_bitcast_masked_shift( ; CHECK-SAME: <16 x i8> [[ARG1:%.*]], <16 x i8> [[ARG2:%.*]]) { ; CHECK-NEXT: [[AND:%.*]] = and <16 x i8> [[ARG1]], splat (i8 3)