-
Notifications
You must be signed in to change notification settings - Fork 14.4k
[SelectionDAG] Simplify vselect true, T, F -> T #100992
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
Changes from all commits
52d1103
4efe9db
7417903
15400c1
4552d30
4eee8f5
4de34ee
64f52d9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9924,15 +9924,8 @@ SDValue SelectionDAG::simplifySelect(SDValue Cond, SDValue T, SDValue F) { | |
|
||
// select true, T, F --> T | ||
// select false, T, F --> F | ||
if (auto *CondC = dyn_cast<ConstantSDNode>(Cond)) | ||
return CondC->isZero() ? F : T; | ||
|
||
// TODO: This should simplify VSELECT with non-zero constant condition using | ||
// something like this (but check boolean contents to be complete?): | ||
if (ConstantSDNode *CondC = isConstOrConstSplat(Cond, /*AllowUndefs*/ false, | ||
/*AllowTruncation*/ true)) | ||
if (CondC->isZero()) | ||
return F; | ||
if (auto C = isBoolConstant(Cond, /*AllowTruncation=*/true)) | ||
return *C ? T : F; | ||
|
||
// select ?, T, T --> T | ||
if (T == F) | ||
|
@@ -13124,6 +13117,31 @@ SDNode *SelectionDAG::isConstantFPBuildVectorOrConstantFP(SDValue N) const { | |
return nullptr; | ||
} | ||
|
||
std::optional<bool> SelectionDAG::isBoolConstant(SDValue N, | ||
bool AllowTruncation) const { | ||
ConstantSDNode *Const = isConstOrConstSplat(N, false, AllowTruncation); | ||
if (!Const) | ||
return std::nullopt; | ||
|
||
const APInt &CVal = Const->getAPIntValue(); | ||
switch (TLI->getBooleanContents(N.getValueType())) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It might be safer if we only accept the 'clean' 1/0, -1/0 and 1b/0b T/F values and std::nullopt otherwise. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah I see what you meant by the original signature you suggested, that makes sense There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks - an alternative would be an optional result that returns the exact match - which would mean we only need one call in simplifySelect. No strong preference on this one though tbh - as long as we only accept the 'clean' boolean contents values. |
||
case TargetLowering::ZeroOrOneBooleanContent: | ||
if (CVal.isOne()) | ||
return true; | ||
if (CVal.isZero()) | ||
return false; | ||
return std::nullopt; | ||
case TargetLowering::ZeroOrNegativeOneBooleanContent: | ||
if (CVal.isAllOnes()) | ||
return true; | ||
if (CVal.isZero()) | ||
return false; | ||
return std::nullopt; | ||
case TargetLowering::UndefinedBooleanContent: | ||
return CVal[0]; | ||
} | ||
} | ||
|
||
void SelectionDAG::createOperands(SDNode *Node, ArrayRef<SDValue> Vals) { | ||
assert(!Node->OperandList && "Node already has operands"); | ||
assert(SDNode::getMaxNumOperands() >= Vals.size() && | ||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,19 @@ | ||||||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 | ||||||
; RUN: llc < %s -mtriple=riscv64 -mattr=+v -verify-machineinstrs | FileCheck %s | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Don't need to add -verify-machineinstrs in any random test There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I specifically added it for this test since it's dealing with RVV instructions. After we migrated the RISCVInsertVSETVLI pass to operate on LiveIntervals it really helps to have the machine verifier check that they're intact. It's already caught quite a few issues just on the existing RVV codegen tests alone. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. They'll get caught in expensive_checks builds. Unless this test is specifically trying to stress a verifier error, which it isn't, it's just wasting test time There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is already the de-facto for the RVV in-tree tests:
I get your point about slow test times but we rely very heavily on this for coverage on RISCVInsertVSETVLI. Should we create a separate issue to discuss this outside of this PR There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right I think this is a long standing issue, and we have thousands of violations. It defeats the point of having a separate EXPENSIVE_CHECKS behavior There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Do we have a RISCV expensive checks bot? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wouldn't the x86_64 expensive checks bot catch this? https://lab.llvm.org/buildbot/#/builders/16 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I think it would. I just wasn't sure what targets it builds. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Created #102092 to separate out this discussion |
||||||
|
||||||
define <vscale x 1 x i64> @all_ones(<vscale x 1 x i64> %true, <vscale x 1 x i64> %false, i32 %evl) { | ||||||
; CHECK-LABEL: all_ones: | ||||||
; CHECK: # %bb.0: | ||||||
; CHECK-NEXT: ret | ||||||
%v = call <vscale x 1 x i64> @llvm.vp.select.nxv1i64(<vscale x 1 x i1> splat (i1 true), <vscale x 1 x i64> %true, <vscale x 1 x i64> %false, i32 %evl) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also test the all false case? Plus another target with the other bits behavior? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I tried creating a test case on r600 which seems to have the different behaviour but couldn't come up with anything meaningful. Mainly because the combine kicks in when the condition vector is at nxi1, so every behaviour considers it true. |
||||||
ret <vscale x 1 x i64> %v | ||||||
} | ||||||
|
||||||
define <vscale x 1 x i64> @all_zeroes(<vscale x 1 x i64> %true, <vscale x 1 x i64> %false, i32 %evl) { | ||||||
; CHECK-LABEL: all_zeroes: | ||||||
; CHECK: # %bb.0: | ||||||
; CHECK-NEXT: vmv1r.v v8, v9 | ||||||
; CHECK-NEXT: ret | ||||||
%v = call <vscale x 1 x i64> @llvm.vp.select.nxv1i64(<vscale x 1 x i1> splat (i1 false), <vscale x 1 x i64> %true, <vscale x 1 x i64> %false, i32 %evl) | ||||||
ret <vscale x 1 x i64> %v | ||||||
} |
Uh oh!
There was an error while loading. Please reload this page.