I have updated TargetLowering::isConstTrueVal to also consider
SPLAT_VECTOR nodes with constant integer operands. This allows the
optimisation to also work for targets that support scalable vectors.
Details
Diff Detail
Unit Tests
Time | Test | |
---|---|---|
36,830 ms | x64 debian > libFuzzer.libFuzzer::fork.test |
Event Timeline
Nice, I'd missed that one. I was going to ask about SPLAT_VECTOR_PARTS but I'm not sure we could get a test for that, seeing as I think it's only generated for 64-bit integer splats on RV32.
llvm/test/CodeGen/RISCV/rvv/cmp-folds.ll | ||
---|---|---|
3 | I think using --check-prefixes=CHECK,RV32 is fairly common in our RVV testing and looks like it'd help remove all duplicate checks. |
llvm/test/CodeGen/RISCV/rvv/cmp-folds.ll | ||
---|---|---|
3 | Good suggestion, thanks! |
llvm/test/CodeGen/RISCV/rvv/cmp-folds.ll | ||
---|---|---|
3 | Oh but of course if there's no use of the RV32 or RV64 checks then lit will fail, sorry about that: I always forget. Sounds like you can just use FileCheck %s |
llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp | ||
---|---|---|
3175 | I think we have to support the truncating case as with BUILD_VECTOR above, don't we? |
llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp | ||
---|---|---|
3175 | Hmm, I looked at the definition of SPLAT_VECTOR and you're right - the operand is allowed to be wider than the vector element type of the result. I hadn't realised that :(. The only problem is that I have absolutely no idea how to write a test case for this using IR! I'm not sure if there is a way to create a splat (using SPLAT_VECTOR) in IR that is truncating. Unless you know of any RISCV examples where this would happen? |
llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp | ||
---|---|---|
3175 | Hmm, it would definitely happen during legalization as we only have either i32 (RV32) or i64 (RV64) as legal integer types, so most splats, really, like <vscale x 1 x i8> with a constant integer. But you'd need to be calling this during/after legalization. So no I'm not sure it's testable, per se. What you've got looks right, though? |
llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp | ||
---|---|---|
3160 | Instead of checking for SPLAT_VECTOR explicitly, how about: if (auto *CN = dyn_cast<ConstantSDNode>(N)) { CVal = CN->getAPIntValue(); } else if (isConstantSplatVector(N, CVal)) { unsigned EltWidth = N->getValueType(0).getScalarSizeInBits(); if (EltWidth < CVal.getBitwidth()) CVal = CVal.trunc(EltWidth); } else return false; |
llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp | ||
---|---|---|
3160 | Sadly this doesn't work because isConstantSplatVector demands the element width of the result be the same as the element width in the BuildVectorSDNode, which means we end up with lots of failing tests. It's just a minor point, but isConstantSplatVector also permits FP splats, so we'd have to restrict it to integer too. |
llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp | ||
---|---|---|
3160 | In that case, maybe you can use ConstantSDNode* llvm::isConstOrConstSplat(SDValue N, bool AllowUndefs, bool AllowTruncation) which allows you to specify whether truncation is allowed? It's bonkers how many of these functions exist... |
Thanks for the change, I think this is an improvement since we can now reuse some existing code for recognising the splat!
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | ||
---|---|---|
911 ↗ | (On Diff #403963) | Can you update isConstFalseVal as well to only take an SDValue as part of this patch? |
Instead of checking for SPLAT_VECTOR explicitly, how about: