Fixes https://github.com/llvm/llvm-project/issues/51558.
The changes were ported from https://reviews.llvm.org/D111858 with some differences specific to aarch64 backend.
Differential D118595
[AARCH64][DAGCombine] Add combine for negation of CSEL absolute value pattern. sunho on Jan 31 2022, 3:54 AM. Authored by
Details Fixes https://github.com/llvm/llvm-project/issues/51558. The changes were ported from https://reviews.llvm.org/D111858 with some differences specific to aarch64 backend.
Diff Detail
Event TimelineComment Actions Hello. This sounds good. It is similar to the patch in D112204 (but I din't have any time to continue that, glad to see you looking into the same thing!) Feel free to steal what is useful from it, if you thing the suggested simplification is a good idea.
Comment Actions I like your method! It's always reducing negation or keeping the same number of negation unless x and y are both non-negative and it can account for nabs case very well. I was trying to tidy your patch a bit and add some more test cases to address the comments by david-arm and submit it here. However, one thing came to concern me. When one of x and y are negative maximum of that integer type (e.g. -128 for int8), then folding negation can nullify signed integer overflows that would have happended if not folded. For instance, if you have -csel(-x,-y), then it will be folded to csel(x,y). If x was the negative maximum of that integer type, it would lead to singed integer overflow in the original form (-(-128)), but it will not after folded. I'm not sure whether I can just consider this case UB and fold it. Could you give me some advice on this? Comment Actions IIUC, if nsw flag is not specified it will wrap around, then -(-128) = -128, still yielding the same result. Even if nsw flag is specified, I can define poison value as anything I want so it's still fine? Comment Actions https://alive2.llvm.org/ce/z/2KoTdr It always passes unless I put nsw on sub in tgt block. I guess that means it's okay.
Comment Actions Sorry for the delay. I've separated commits that adds tests to https://reviews.llvm.org/D120214, and make this commit only show the difference between older version. Comment Actions Cheers! Can you commit on my behalf? Author name: sunho Comment Actions Whoops. I put the wrong differential revision on that commit. Sorry about that. https://reviews.llvm.org/rGd6a9eec2382559aeae3bb87761afa1b6d351e9a5 should have pointed here instead. |
I think we might be able to generalize this a bit, possibly simplifying it in the process. If we have neg (csel x, y, cc), we can convert to csel (neg x), (neg y), cc, and providing at least one of x and y simplify it will be the same cost or cheaper (with a csneg operation).
I think that means that the condition is unimportant, and we won't need to emit the Add. It won't handle all the same patterns this does, both might be quite rare for cases that are not -abs (as llvm will have often optimized before this point already), but might be more straight forward.