From 2e999b7dd1934a44d38c3a753460f1e5a217e9a5 Mon Sep 17 00:00:00 2001 From: Philip Reames Date: Tue, 1 Nov 2022 09:22:24 -0700 Subject: [PATCH] Allow scalable vectors in ComputeNumSignBits and isKnownNonNull This is a follow up to D136470 which extends the same scheme used there to ComputeNumSignBits and isKnownNonNull. As a reminder, for scalable vectors we track a single bit which is implicitly broadcast to all lanes. We do not know how many lanes there are statically, and thus have to be conservative along paths which require exact sizes. Differential Revision: https://reviews.llvm.org/D137046 --- llvm/lib/Analysis/ValueTracking.cpp | 28 +++++----------------- llvm/test/Transforms/InstCombine/logical-select.ll | 12 ++++------ llvm/test/Transforms/InstCombine/select.ll | 7 ++---- 3 files changed, 13 insertions(+), 34 deletions(-) diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 0606ce7..be00950 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -375,11 +375,6 @@ static unsigned ComputeNumSignBits(const Value *V, const APInt &DemandedElts, static unsigned ComputeNumSignBits(const Value *V, unsigned Depth, const Query &Q) { - // FIXME: We currently have no way to represent the DemandedElts of a scalable - // vector - if (isa(V->getType())) - return 1; - auto *FVTy = dyn_cast(V->getType()); APInt DemandedElts = FVTy ? APInt::getAllOnes(FVTy->getNumElements()) : APInt(1, 1); @@ -2449,10 +2444,6 @@ static bool isNonZeroRecurrence(const PHINode *PN) { /// Supports values with integer or pointer type and vectors of integers. bool isKnownNonZero(const Value *V, const APInt &DemandedElts, unsigned Depth, const Query &Q) { - // FIXME: We currently have no way to represent the DemandedElts of a scalable - // vector - if (isa(V->getType())) - return false; #ifndef NDEBUG Type *Ty = V->getType(); @@ -2574,14 +2565,18 @@ bool isKnownNonZero(const Value *V, const APInt &DemandedElts, unsigned Depth, // Note that we have to take special care to avoid looking through // truncating casts, e.g., int2ptr/ptr2int with appropriate sizes, as well // as casts that can alter the value, e.g., AddrSpaceCasts. - if (Q.DL.getTypeSizeInBits(I->getOperand(0)->getType()).getFixedSize() <= + if (!isa(I->getOperand(0)->getType()) && + !isa(I->getType()) && + Q.DL.getTypeSizeInBits(I->getOperand(0)->getType()).getFixedSize() <= Q.DL.getTypeSizeInBits(I->getType()).getFixedSize()) return isKnownNonZero(I->getOperand(0), Depth, Q); break; case Instruction::PtrToInt: // Similar to int2ptr above, we can look through ptr2int here if the cast // is a no-op or an extend and not a truncate. - if (Q.DL.getTypeSizeInBits(I->getOperand(0)->getType()).getFixedSize() <= + if (!isa(I->getOperand(0)->getType()) && + !isa(I->getType()) && + Q.DL.getTypeSizeInBits(I->getOperand(0)->getType()).getFixedSize() <= Q.DL.getTypeSizeInBits(I->getType()).getFixedSize()) return isKnownNonZero(I->getOperand(0), Depth, Q); break; @@ -2740,11 +2735,6 @@ bool isKnownNonZero(const Value *V, const APInt &DemandedElts, unsigned Depth, } bool isKnownNonZero(const Value* V, unsigned Depth, const Query& Q) { - // FIXME: We currently have no way to represent the DemandedElts of a scalable - // vector - if (isa(V->getType())) - return false; - auto *FVTy = dyn_cast(V->getType()); APInt DemandedElts = FVTy ? APInt::getAllOnes(FVTy->getNumElements()) : APInt(1, 1); @@ -3096,12 +3086,6 @@ static unsigned ComputeNumSignBitsImpl(const Value *V, const APInt &DemandedElts, unsigned Depth, const Query &Q) { Type *Ty = V->getType(); - - // FIXME: We currently have no way to represent the DemandedElts of a scalable - // vector - if (isa(Ty)) - return 1; - #ifndef NDEBUG assert(Depth <= MaxAnalysisRecursionDepth && "Limit Search Depth"); diff --git a/llvm/test/Transforms/InstCombine/logical-select.ll b/llvm/test/Transforms/InstCombine/logical-select.ll index 8fe517a..4a11335 100644 --- a/llvm/test/Transforms/InstCombine/logical-select.ll +++ b/llvm/test/Transforms/InstCombine/logical-select.ll @@ -742,13 +742,11 @@ define <2 x i64> @bitcast_vec_cond(<16 x i1> %cond, <2 x i64> %c, <2 x i64> %d) define @bitcast_vec_cond_scalable( %cond, %c, %d) { ; CHECK-LABEL: @bitcast_vec_cond_scalable( -; CHECK-NEXT: [[S:%.*]] = sext [[COND:%.*]] to -; CHECK-NEXT: [[T9:%.*]] = bitcast [[S]] to -; CHECK-NEXT: [[NOTT9:%.*]] = xor [[T9]], shufflevector ( insertelement ( poison, i64 -1, i32 0), poison, zeroinitializer) -; CHECK-NEXT: [[T11:%.*]] = and [[NOTT9]], [[C:%.*]] -; CHECK-NEXT: [[T12:%.*]] = and [[T9]], [[D:%.*]] -; CHECK-NEXT: [[R:%.*]] = or [[T11]], [[T12]] -; CHECK-NEXT: ret [[R]] +; CHECK-NEXT: [[TMP1:%.*]] = bitcast [[D:%.*]] to +; CHECK-NEXT: [[TMP2:%.*]] = bitcast [[C:%.*]] to +; CHECK-NEXT: [[TMP3:%.*]] = select [[COND:%.*]], [[TMP1]], [[TMP2]] +; CHECK-NEXT: [[TMP4:%.*]] = bitcast [[TMP3]] to +; CHECK-NEXT: ret [[TMP4]] ; %s = sext %cond to %t9 = bitcast %s to diff --git a/llvm/test/Transforms/InstCombine/select.ll b/llvm/test/Transforms/InstCombine/select.ll index cc72e35..e16f01bb 100644 --- a/llvm/test/Transforms/InstCombine/select.ll +++ b/llvm/test/Transforms/InstCombine/select.ll @@ -3409,11 +3409,10 @@ define @and_constant_select_svec( %x, %b } -; TODO: shl should be nsw define @scalable_sign_bits( %x) { ; CHECK-LABEL: @scalable_sign_bits( ; CHECK-NEXT: [[A:%.*]] = sext [[X:%.*]] to -; CHECK-NEXT: [[B:%.*]] = shl [[A]], shufflevector ( insertelement ( poison, i32 16, i32 0), poison, zeroinitializer) +; CHECK-NEXT: [[B:%.*]] = shl nsw [[A]], shufflevector ( insertelement ( poison, i32 16, i32 0), poison, zeroinitializer) ; CHECK-NEXT: ret [[B]] ; %a = sext %x to @@ -3421,12 +3420,10 @@ define @scalable_sign_bits( %x) { ret %b } -; TODO: can use ult define @scalable_non_zero( %x) { ; CHECK-LABEL: @scalable_non_zero( ; CHECK-NEXT: [[A:%.*]] = or [[X:%.*]], shufflevector ( insertelement ( poison, i32 1, i32 0), poison, zeroinitializer) -; CHECK-NEXT: [[B:%.*]] = add nsw [[A]], shufflevector ( insertelement ( poison, i32 -1, i32 0), poison, zeroinitializer) -; CHECK-NEXT: [[CMP:%.*]] = icmp ult [[B]], shufflevector ( insertelement ( poison, i32 56, i32 0), poison, zeroinitializer) +; CHECK-NEXT: [[CMP:%.*]] = icmp ule [[A]], shufflevector ( insertelement ( poison, i32 56, i32 0), poison, zeroinitializer) ; CHECK-NEXT: ret [[CMP]] ; %a = or %x, shufflevector ( insertelement ( poison, i32 1, i32 0), poison, zeroinitializer) -- 2.7.4