-
Notifications
You must be signed in to change notification settings - Fork 10.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SimplifyCFG fails to merge all == -1 into a single block #62311
Comments
Let me know if I'm off the mark
These changes would fix this 🙂 ref: |
Hi @khei4, |
@xgupta Not yet. You can do it, thanks! |
I did some investigation. It is like this working for allzeros case (combining two cmp instruction to single one) -
/// Try to fold (icmp(A & B) ==/!= C) &/| (icmp(A & D) ==/!= E)
/// into a single (icmp(A & X) ==/!= Y).
static Value *foldLogOpOfMaskedICmps(ICmpInst *LHS, ICmpInst *RHS, bool IsAnd,
bool IsLogical,
InstCombiner::BuilderTy &Builder) {
Value *A = nullptr, *B = nullptr, *C = nullptr, *D = nullptr, *E = nullptr;
ICmpInst::Predicate PredL = LHS->getPredicate(), PredR = RHS->getPredicate();
std::optional<std::pair<unsigned, unsigned>> MaskPair =
getMaskedTypeForICmpPair(A, B, C, D, E, LHS, RHS, PredL, PredR);
unsigned LHSMask = MaskPair->first;
unsigned RHSMask = MaskPair->second;
unsigned Mask = LHSMask & RHSMask;
// In most cases we're going to produce an EQ for the "&&" case.
ICmpInst::Predicate NewCC = IsAnd ? ICmpInst::ICMP_EQ : ICmpInst::ICMP_NE;
if (Mask & Mask_AllZeros) {
// (icmp eq (A & B), 0) & (icmp eq (A & D), 0)
-> (icmp eq (A & (B|D)), 0)
Value *NewOr = Builder.CreateOr(B, D);
Value *NewAnd = Builder.CreateAnd(A, NewOr);
// We can't use C as zero because we might actually handle
// (icmp ne (A & B), B) & (icmp ne (A & D), D)
// with B and D, having a single bit set.
Value *Zero = Constant::getNullValue(A->getType());
return Builder.CreateICmp(NewCC, NewAnd, Zero);
}
return nullptr;
} I am next working on making instcombine to work with 1 case. |
Thanks @xgupta ! |
https://gcc.godbolt.org/z/vn1v37Ger
Branched off from #59998 - all but the last comparisons are merged into the same basic block, preventing vectorization.
to
Interestingly, the equivalent 'allzeros' has the same problem on the first SimplifyCFG pass, but a later pass merges the last comparison as well: https://gcc.godbolt.org/z/oe8cjY137
The text was updated successfully, but these errors were encountered: