diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp index 674557b1caedf..cdd85d4ba84ea 100644 --- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp +++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp @@ -4384,6 +4384,14 @@ bool CombinerHelper::matchBitfieldExtractFromShrAnd( if (ShrAmt < 0 || ShrAmt >= Size) return false; + // If the shift subsumes the mask, emit the 0 directly. + if (0 == (SMask >> ShrAmt)) { + MatchInfo = [=](MachineIRBuilder &B) { + B.buildConstant(Dst, 0); + }; + return true; + } + // Check that ubfx can do the extraction, with no holes in the mask. uint64_t UMask = SMask; UMask |= maskTrailingOnes(ShrAmt); diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/form-bitfield-extract-from-shr-and.mir b/llvm/test/CodeGen/AArch64/GlobalISel/form-bitfield-extract-from-shr-and.mir index 55a75b1d03fda..c8c5b157f4244 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/form-bitfield-extract-from-shr-and.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/form-bitfield-extract-from-shr-and.mir @@ -188,3 +188,20 @@ body: | %4:_(s32) = G_LSHR %3, %2 $w0 = COPY %4(s32) ... +--- +name: zero_from_large_shift +legalized: true +body: | + bb.1.entry: + ; CHECK-LABEL: name: zero_from_large_shift + ; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0 + ; CHECK-NEXT: $x0 = COPY [[C]](s64) + %2:_(s32) = COPY $w0 + %1:_(s8) = G_TRUNC %2:_(s32) + %3:_(s8) = G_ASSERT_ZEXT %1:_, 1 + %5:_(s64) = G_CONSTANT i64 1 + %7:_(s64) = G_ANYEXT %3:_(s8) + %4:_(s64) = G_AND %7:_, %5:_ + %6:_(s64) = G_LSHR %4:_, %5:_(s64) + $x0 = COPY %6:_(s64) +...