diff --git a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp index ea4ab73700cf0..4d4f0bc3a190a 100644 --- a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp +++ b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp @@ -870,6 +870,37 @@ void GISelValueTracking::computeKnownBitsImpl(Register R, KnownBits &Known, computeKnownBitsImpl(InVec, Known, DemandedSrcElts, Depth + 1); break; } + case TargetOpcode::G_INSERT_VECTOR_ELT: { + GInsertVectorElement &Insert = cast(MI); + Register InVec = Insert.getVectorReg(); + Register InVal = Insert.getElementReg(); + Register EltNo = Insert.getIndexReg(); + LLT VecVT = MRI.getType(InVec); + + if (VecVT.isScalableVector()) + break; + + auto ConstEltNo = getIConstantVRegVal(EltNo, MRI); + unsigned NumElts = VecVT.getNumElements(); + + bool DemandedVal = true; + APInt DemandedVecElts = DemandedElts; + if (ConstEltNo && ConstEltNo->ult(NumElts)) { + unsigned EltIdx = ConstEltNo->getZExtValue(); + DemandedVal = !!DemandedElts[EltIdx]; + DemandedVecElts.clearBit(EltIdx); + } + Known.setAllConflict(); + if (DemandedVal) { + computeKnownBitsImpl(InVal, Known2, APInt(1, 1), Depth + 1); + Known = Known.intersectWith(Known2.zextOrTrunc(BitWidth)); + } + if (!!DemandedVecElts) { + computeKnownBitsImpl(InVec, Known2, DemandedVecElts, Depth + 1); + Known = Known.intersectWith(Known2); + } + break; + } case TargetOpcode::G_SHUFFLE_VECTOR: { APInt DemandedLHS, DemandedRHS; // Collect the known bits that are shared by every vector element referenced diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-insert-vector.mir b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-insert-vector.mir new file mode 100644 index 0000000000000..5a3985a109a0c --- /dev/null +++ b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-insert-vector.mir @@ -0,0 +1,99 @@ +# NOTE: Assertions have been autogenerated by utils/update_givaluetracking_test_checks.py UTC_ARGS: --version 6 +# RUN: llc -mtriple aarch64 -passes="print" %s -filetype=null 2>&1 | FileCheck %s + +--- +name: all_knownbits_const_idx +body: | + bb.0: + ; CHECK-LABEL: name: @all_knownbits_const_idx + ; CHECK-NEXT: %idx:_ KnownBits:0000000000000000000000000000000000000000000000000000000000000001 SignBits:63 + ; CHECK-NEXT: %1:_ KnownBits:00000011 SignBits:6 + ; CHECK-NEXT: %2:_ KnownBits:00001111 SignBits:4 + ; CHECK-NEXT: %3:_ KnownBits:0000??11 SignBits:4 + ; CHECK-NEXT: %4:_ KnownBits:00000110 SignBits:5 + ; CHECK-NEXT: %5:_ KnownBits:00000?1? SignBits:5 + %idx:_(i64) = G_CONSTANT i64 1 + %1:_(i8) = G_CONSTANT i8 3 + %2:_(i8) = G_CONSTANT i8 15 + %3:_(<2 x i8>) = G_BUILD_VECTOR %1, %2 + %4:_(i8) = G_CONSTANT i8 6 + %5:_(<2 x i8>) = G_INSERT_VECTOR_ELT %3, %4, %idx +... +--- +name: all_knownbits_unknown_lane +body: | + bb.0: + ; CHECK-LABEL: name: @all_knownbits_unknown_lane + ; CHECK-NEXT: %idx:_ KnownBits:???????????????????????????????????????????????????????????????? SignBits:1 + ; CHECK-NEXT: %1:_ KnownBits:00000011 SignBits:6 + ; CHECK-NEXT: %2:_ KnownBits:00001111 SignBits:4 + ; CHECK-NEXT: %3:_ KnownBits:0000??11 SignBits:4 + ; CHECK-NEXT: %4:_ KnownBits:00000110 SignBits:5 + ; CHECK-NEXT: %5:_ KnownBits:0000??1? SignBits:4 + %idx:_(i64) = COPY $x0 + %1:_(i8) = G_CONSTANT i8 3 + %2:_(i8) = G_CONSTANT i8 15 + %3:_(<2 x i8>) = G_BUILD_VECTOR %1, %2 + %4:_(i8) = G_CONSTANT i8 6 + %5:_(<2 x i8>) = G_INSERT_VECTOR_ELT %3, %4, %idx +... +--- +name: all_knownbits_const_idx_demand_0 +body: | + bb.0: + ; CHECK-LABEL: name: @all_knownbits_const_idx_demand_0 + ; CHECK-NEXT: %idx0:_ KnownBits:0000000000000000000000000000000000000000000000000000000000000000 SignBits:64 + ; CHECK-NEXT: %1:_ KnownBits:00000011 SignBits:6 + ; CHECK-NEXT: %2:_ KnownBits:00001111 SignBits:4 + ; CHECK-NEXT: %3:_ KnownBits:0000??11 SignBits:4 + ; CHECK-NEXT: %4:_ KnownBits:00000110 SignBits:5 + ; CHECK-NEXT: %5:_ KnownBits:0000?11? SignBits:4 + ; CHECK-NEXT: %6:_ KnownBits:00000110 SignBits:5 + %idx0:_(i64) = G_CONSTANT i64 0 + %1:_(i8) = G_CONSTANT i8 3 + %2:_(i8) = G_CONSTANT i8 15 + %3:_(<2 x i8>) = G_BUILD_VECTOR %1, %2 + %4:_(i8) = G_CONSTANT i8 6 + %5:_(<2 x i8>) = G_INSERT_VECTOR_ELT %3, %4, %idx0 + %6:_(i8) = G_EXTRACT_VECTOR_ELT %5, %idx0 +... +--- +name: all_knownbits_const_idx_demand_1 +body: | + bb.0: + ; CHECK-LABEL: name: @all_knownbits_const_idx_demand_1 + ; CHECK-NEXT: %idx0:_ KnownBits:0000000000000000000000000000000000000000000000000000000000000000 SignBits:64 + ; CHECK-NEXT: %idx1:_ KnownBits:0000000000000000000000000000000000000000000000000000000000000001 SignBits:63 + ; CHECK-NEXT: %2:_ KnownBits:00000011 SignBits:6 + ; CHECK-NEXT: %3:_ KnownBits:00001111 SignBits:4 + ; CHECK-NEXT: %4:_ KnownBits:0000??11 SignBits:4 + ; CHECK-NEXT: %5:_ KnownBits:00000110 SignBits:5 + ; CHECK-NEXT: %6:_ KnownBits:0000?11? SignBits:4 + ; CHECK-NEXT: %7:_ KnownBits:00001111 SignBits:4 + %idx0:_(i64) = G_CONSTANT i64 0 + %idx1:_(i64) = G_CONSTANT i64 1 + %2:_(i8) = G_CONSTANT i8 3 + %3:_(i8) = G_CONSTANT i8 15 + %4:_(<2 x i8>) = G_BUILD_VECTOR %2, %3 + %5:_(i8) = G_CONSTANT i8 6 + %6:_(<2 x i8>) = G_INSERT_VECTOR_ELT %4, %5, %idx0 + %7:_(i8) = G_EXTRACT_VECTOR_ELT %6, %idx1 +... +--- +name: all_knownbits_const_idx_outofrange +body: | + bb.0: + ; CHECK-LABEL: name: @all_knownbits_const_idx_outofrange + ; CHECK-NEXT: %idx:_ KnownBits:0000000000000000000000000000000000000000000000000000000000000010 SignBits:62 + ; CHECK-NEXT: %1:_ KnownBits:00000011 SignBits:6 + ; CHECK-NEXT: %2:_ KnownBits:00001111 SignBits:4 + ; CHECK-NEXT: %3:_ KnownBits:0000??11 SignBits:4 + ; CHECK-NEXT: %4:_ KnownBits:00000110 SignBits:5 + ; CHECK-NEXT: %5:_ KnownBits:0000??1? SignBits:4 + %idx:_(i64) = G_CONSTANT i64 2 + %1:_(i8) = G_CONSTANT i8 3 + %2:_(i8) = G_CONSTANT i8 15 + %3:_(<2 x i8>) = G_BUILD_VECTOR %1, %2 + %4:_(i8) = G_CONSTANT i8 6 + %5:_(<2 x i8>) = G_INSERT_VECTOR_ELT %3, %4, %idx +...