[llvm] [AArch64] Allow splitting bitmasks for EOR/ORR. (PR #150394)
Paul Walker via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 31 08:03:19 PDT 2025
================
@@ -190,19 +191,48 @@ static bool splitBitmaskImm(T Imm, unsigned RegSize, T &Imm1Enc, T &Imm2Enc) {
return true;
}
+template <typename T>
+static bool splitDisjointBitmaskImm(T Imm, unsigned RegSize, T &Imm1Enc,
+ T &Imm2Enc) {
+ // Try to split a bitmask of the form 0b00000000011000000000011110000000 into
+ // two disjoint masks such as 0b00000000011000000000000000000000 and
+ // 0b00000000000000000000011110000000 where the inclusive/exclusive OR of the
+ // new masks match the original mask.
+ unsigned LowestBitSet = llvm::countr_zero(Imm);
+ unsigned LowestGapBitUnset =
+ LowestBitSet + llvm::countr_one(Imm >> LowestBitSet);
+
+ // Create a mask for the least significant group of consecutive ones.
+ T NewImm1 = (static_cast<T>(1) << LowestGapBitUnset) -
+ (static_cast<T>(1) << LowestBitSet);
+ // Create a disjoint mask for the remaining ones.
+ T NewImm2 = Imm & ~NewImm1;
+ assert(((NewImm1 & NewImm2) == 0) && "Non-disjoint immediates!");
+
+ if (AArch64_AM::isLogicalImmediate(NewImm2, RegSize)) {
+ assert(((NewImm1 | NewImm2) == Imm) && "Invalid immediates!");
+ assert(((NewImm1 ^ NewImm2) == Imm) && "Invalid immediates!");
+ Imm1Enc = AArch64_AM::encodeLogicalImmediate(NewImm1, RegSize);
+ Imm2Enc = AArch64_AM::encodeLogicalImmediate(NewImm2, RegSize);
+ return true;
+ }
----------------
paulwalker-arm wrote:
A minor niggle but is there a good reason to deviate from the way this is structured in `splitBitmaskImm`?
https://github.com/llvm/llvm-project/pull/150394
More information about the llvm-commits
mailing list