diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp --- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -2344,8 +2344,12 @@ // not create unnecessary casts if the types already match. Type *SelTy = A->getType(); if (auto *VecTy = dyn_cast(Cond->getType())) { + // For a fixed or scalable vector get N from <{vscale x} N x iM> unsigned Elts = VecTy->getElementCount().getKnownMinValue(); - Type *EltTy = Builder.getIntNTy(SelTy->getPrimitiveSizeInBits() / Elts); + // For a fixed or scalable vector, get the size in bits of N x iM; for a + // scalar this is just M. + unsigned SelEltSize = SelTy->getPrimitiveSizeInBits().getKnownMinSize(); + Type *EltTy = Builder.getIntNTy(SelEltSize / Elts); SelTy = VectorType::get(EltTy, VecTy->getElementCount()); } Value *BitcastC = Builder.CreateBitCast(C, SelTy); diff --git a/llvm/test/Transforms/InstCombine/logical-select.ll b/llvm/test/Transforms/InstCombine/logical-select.ll --- a/llvm/test/Transforms/InstCombine/logical-select.ll +++ b/llvm/test/Transforms/InstCombine/logical-select.ll @@ -471,6 +471,18 @@ ret <4 x i1> %or } +define @vec_of_bools_scalable( %a, %c, %d) { +; CHECK-LABEL: @vec_of_bools_scalable( +; CHECK-NEXT: [[TMP1:%.*]] = select [[A:%.*]], [[C:%.*]], [[D:%.*]] +; CHECK-NEXT: ret [[TMP1]] +; + %b = xor %a, shufflevector ( insertelement ( poison, i1 true, i32 0), poison, zeroinitializer) + %t11 = and %a, %c + %t12 = and %b, %d + %r = or %t11, %t12 + ret %r +} + define i4 @vec_of_casted_bools(i4 %a, i4 %b, <4 x i1> %c) { ; CHECK-LABEL: @vec_of_casted_bools( ; CHECK-NEXT: [[TMP1:%.*]] = bitcast i4 [[B:%.*]] to <4 x i1> @@ -488,6 +500,25 @@ ret i4 %or } +define @vec_of_casted_bools_scalable( %a, %b, %cond) { +; CHECK-LABEL: @vec_of_casted_bools_scalable( +; CHECK-NEXT: [[TMP1:%.*]] = bitcast [[A:%.*]] to +; CHECK-NEXT: [[TMP2:%.*]] = bitcast [[B:%.*]] to +; CHECK-NEXT: [[TMP3:%.*]] = select [[COND:%.*]], [[TMP1]], [[TMP2]] +; CHECK-NEXT: [[TMP4:%.*]] = bitcast [[TMP3]] to +; CHECK-NEXT: ret [[TMP4]] +; + %scond = sext %cond to + %notcond = xor %cond, shufflevector ( insertelement ( poison, i1 true, i32 0), poison, zeroinitializer) + %snotcond = sext %notcond to + %bc1 = bitcast %scond to + %bc2 = bitcast %snotcond to + %and1 = and %a, %bc1 + %and2 = and %bc2, %b + %or = or %and1, %and2 + ret %or +} + ; Inverted 'and' constants mean this is a select which is canonicalized to a shuffle. define <4 x i32> @vec_sel_consts(<4 x i32> %a, <4 x i32> %b) {