diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index dbceb8e557849..6e460de65e65b 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -2249,6 +2249,11 @@ static void computeKnownBitsFromOperator(const Operator *I, break; } case Instruction::ShuffleVector: { + if (auto *Splat = getSplatValue(I)) { + computeKnownBits(Splat, Known, Q, Depth + 1); + break; + } + auto *Shuf = dyn_cast(I); // FIXME: Do we need to handle ConstantExpr involving shufflevectors? if (!Shuf) { diff --git a/llvm/test/Transforms/InstCombine/known-bits.ll b/llvm/test/Transforms/InstCombine/known-bits.ll index f8c97d86a9230..da2123a5dfe74 100644 --- a/llvm/test/Transforms/InstCombine/known-bits.ll +++ b/llvm/test/Transforms/InstCombine/known-bits.ll @@ -2425,6 +2425,23 @@ exit: ret i8 %or2 } +define @scalable_add_to_disjoint_or(i8 %x, range(i32 0, 256) %rhs) { +; CHECK-LABEL: @scalable_add_to_disjoint_or( +; CHECK-NEXT: [[EXTX:%.*]] = zext i8 [[X:%.*]] to i32 +; CHECK-NEXT: [[SHIFT:%.*]] = shl nuw nsw i32 [[EXTX]], 8 +; CHECK-NEXT: [[INSERT:%.*]] = insertelement poison, i32 [[SHIFT]], i64 0 +; CHECK-NEXT: [[SPLAT:%.*]] = shufflevector [[INSERT]], poison, zeroinitializer +; CHECK-NEXT: [[ADD:%.*]] = or disjoint [[SPLAT]], [[RHS:%.*]] +; CHECK-NEXT: ret [[ADD]] +; + %extx = zext i8 %x to i32 + %shift = shl nuw nsw i32 %extx, 8 + %insert = insertelement poison, i32 %shift, i32 0 + %splat = shufflevector %insert, poison, zeroinitializer + %add = add %splat, %rhs + ret %add +} + declare void @dummy() declare void @use(i1) declare void @sink(i8) diff --git a/llvm/test/Transforms/LoopVectorize/AArch64/sve-interleaved-accesses.ll b/llvm/test/Transforms/LoopVectorize/AArch64/sve-interleaved-accesses.ll index 955b4d45d7222..8935010e71676 100644 --- a/llvm/test/Transforms/LoopVectorize/AArch64/sve-interleaved-accesses.ll +++ b/llvm/test/Transforms/LoopVectorize/AArch64/sve-interleaved-accesses.ll @@ -1197,8 +1197,8 @@ define void @PR27626_5(ptr %a, i32 %x, i32 %y, i32 %z, i64 %n) #1 { ; CHECK: vector.body: ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ] ; CHECK-NEXT: [[VEC_IND:%.*]] = phi [ [[INDUCTION]], [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[VECTOR_BODY]] ] -; CHECK-NEXT: [[TMP13:%.*]] = add [[VEC_IND]], splat (i64 -1) -; CHECK-NEXT: [[TMP14:%.*]] = add [[VEC_IND]], splat (i64 -3) +; CHECK-NEXT: [[TMP13:%.*]] = add nsw [[VEC_IND]], splat (i64 -1) +; CHECK-NEXT: [[TMP14:%.*]] = add nsw [[VEC_IND]], splat (i64 -3) ; CHECK-NEXT: [[TMP15:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], [[VEC_IND]] ; CHECK-NEXT: [[TMP16:%.*]] = getelementptr inbounds i32, ptr [[A]], [[TMP13]] ; CHECK-NEXT: [[TMP17:%.*]] = getelementptr inbounds i32, ptr [[A]], [[TMP14]] @@ -1286,7 +1286,7 @@ define void @PR34743(ptr %a, ptr %b, i64 %n) #1 { ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ] ; CHECK-NEXT: [[VECTOR_RECUR:%.*]] = phi [ [[VECTOR_RECUR_INIT]], [[VECTOR_PH]] ], [ [[WIDE_MASKED_GATHER4:%.*]], [[VECTOR_BODY]] ] ; CHECK-NEXT: [[VEC_IND:%.*]] = phi [ [[TMP15]], [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[VECTOR_BODY]] ] -; CHECK-NEXT: [[TMP18:%.*]] = add nuw nsw [[VEC_IND]], splat (i64 1) +; CHECK-NEXT: [[TMP18:%.*]] = or disjoint [[VEC_IND]], splat (i64 1) ; CHECK-NEXT: [[TMP19:%.*]] = add nuw nsw [[VEC_IND]], splat (i64 2) ; CHECK-NEXT: [[TMP20:%.*]] = getelementptr inbounds i16, ptr [[A]], [[TMP18]] ; CHECK-NEXT: [[WIDE_MASKED_GATHER:%.*]] = call @llvm.masked.gather.nxv4i16.nxv4p0( align 4 [[TMP20]], splat (i1 true), poison), !alias.scope [[META34:![0-9]+]]