Index: llvm/include/llvm/Support/KnownBits.h =================================================================== --- llvm/include/llvm/Support/KnownBits.h +++ llvm/include/llvm/Support/KnownBits.h @@ -241,6 +241,12 @@ static KnownBits computeForAddSub(bool Add, bool NSW, const KnownBits &LHS, KnownBits RHS); + /// Insert the bits from a smaller known bits starting at bitPosition. + void insertBits(const KnownBits &SubBits, unsigned BitPosition) { + Zero.insertBits(SubBits.Zero, BitPosition); + One.insertBits(SubBits.One, BitPosition); + } + /// Update known bits based on ANDing with RHS. KnownBits &operator&=(const KnownBits &RHS); Index: llvm/lib/CodeGen/GlobalISel/GISelKnownBits.cpp =================================================================== --- llvm/lib/CodeGen/GlobalISel/GISelKnownBits.cpp +++ llvm/lib/CodeGen/GlobalISel/GISelKnownBits.cpp @@ -387,6 +387,18 @@ Known.Zero.setBitsFrom(SrcBitWidth); break; } + case TargetOpcode::G_MERGE_VALUES: { + Register NumOps = MI.getNumOperands(); + unsigned OpSize = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits(); + + for (unsigned I = 0; I != NumOps - 1; ++I) { + KnownBits SrcOpKnown; + computeKnownBitsImpl(MI.getOperand(I + 1).getReg(), SrcOpKnown, + DemandedElts, Depth + 1); + Known.insertBits(SrcOpKnown, I * OpSize); + } + break; + } } assert(!Known.hasConflict() && "Bits known to be one AND zero?"); Index: llvm/unittests/CodeGen/GlobalISel/KnownBitsTest.cpp =================================================================== --- llvm/unittests/CodeGen/GlobalISel/KnownBitsTest.cpp +++ llvm/unittests/CodeGen/GlobalISel/KnownBitsTest.cpp @@ -555,3 +555,26 @@ EXPECT_EQ((uint64_t)0, Res.One.getZExtValue()); EXPECT_EQ((uint64_t)0xfffffffe, Res.Zero.getZExtValue()); } + + +TEST_F(AArch64GISelMITest, TestKnownBitsMergeValues) { + StringRef MIRString = R"( + %val0:_(s16) = G_CONSTANT i16 35224 + %val1:_(s16) = G_CONSTANT i16 17494 + %val2:_(s16) = G_CONSTANT i16 4659 + %val3:_(s16) = G_CONSTANT i16 43981 + %merge:_(s64) = G_MERGE_VALUES %val0, %val1, %val2, %val3 + %mergecopy:_(s64) = COPY %merge)"; + setUp(MIRString); + if (!TM) + return; + + const uint64_t TestVal = UINT64_C(0xabcd123344568998); + Register CopyMerge = Copies[Copies.size() - 1]; + + GISelKnownBits Info(*MF); + KnownBits Res = Info.getKnownBits(CopyMerge); + EXPECT_EQ(64u, Res.getBitWidth()); + EXPECT_EQ(TestVal, Res.One.getZExtValue()); + EXPECT_EQ(~TestVal, Res.Zero.getZExtValue()); +}