-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[SDag][ARM][RISCV] Allow lowering CTPOP into a libcall #99752
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
Conversation
@llvm/pr-subscribers-backend-risc-v @llvm/pr-subscribers-llvm-selectiondag Author: Sergei Barannikov (s-barannikov) ChangesSome in-tree targets (e.g. ARM) could benefit from this lowering, at least in opt-size mode, but I don't know if the libcall is available in their libgcc, so no tests. Full diff: https://github.com/llvm/llvm-project/pull/99752.diff 2 Files Affected:
diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.def b/llvm/include/llvm/IR/RuntimeLibcalls.def
index 89aaf6d1ad83f..3dd75622b8e43 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.def
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.def
@@ -85,6 +85,9 @@ HANDLE_LIBCALL(NEG_I64, "__negdi2")
HANDLE_LIBCALL(CTLZ_I32, "__clzsi2")
HANDLE_LIBCALL(CTLZ_I64, "__clzdi2")
HANDLE_LIBCALL(CTLZ_I128, "__clzti2")
+HANDLE_LIBCALL(CTPOP_I32, "__popcountsi2")
+HANDLE_LIBCALL(CTPOP_I64, "__popcountdi2")
+HANDLE_LIBCALL(CTPOP_I128, "__popcountti2")
// Floating-point
HANDLE_LIBCALL(ADD_F32, "__addsf3")
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index 9f515739ee048..c0141cfc533b7 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -140,12 +140,9 @@ class SelectionDAGLegalize {
RTLIB::Libcall Call_F128,
RTLIB::Libcall Call_PPCF128,
SmallVectorImpl<SDValue> &Results);
- SDValue ExpandIntLibCall(SDNode *Node, bool isSigned,
- RTLIB::Libcall Call_I8,
- RTLIB::Libcall Call_I16,
- RTLIB::Libcall Call_I32,
- RTLIB::Libcall Call_I64,
- RTLIB::Libcall Call_I128);
+ SDValue ExpandIntLibCall(SDNode *Node, bool IsSigned, RTLIB::Libcall Call_I8,
+ RTLIB::Libcall Call_I16, RTLIB::Libcall Call_I32,
+ RTLIB::Libcall Call_I64, RTLIB::Libcall Call_I128);
void ExpandArgFPLibCall(SDNode *Node,
RTLIB::Libcall Call_F32, RTLIB::Libcall Call_F64,
RTLIB::Libcall Call_F80, RTLIB::Libcall Call_F128,
@@ -2209,7 +2206,7 @@ void SelectionDAGLegalize::ExpandFPLibCall(SDNode* Node,
ExpandFPLibCall(Node, LC, Results);
}
-SDValue SelectionDAGLegalize::ExpandIntLibCall(SDNode* Node, bool isSigned,
+SDValue SelectionDAGLegalize::ExpandIntLibCall(SDNode *Node, bool IsSigned,
RTLIB::Libcall Call_I8,
RTLIB::Libcall Call_I16,
RTLIB::Libcall Call_I32,
@@ -2224,7 +2221,9 @@ SDValue SelectionDAGLegalize::ExpandIntLibCall(SDNode* Node, bool isSigned,
case MVT::i64: LC = Call_I64; break;
case MVT::i128: LC = Call_I128; break;
}
- return ExpandLibCall(LC, Node, isSigned).first;
+ assert(LC != RTLIB::UNKNOWN_LIBCALL &&
+ "LibCall explicitly requested, but not available");
+ return ExpandLibCall(LC, Node, IsSigned).first;
}
/// Expand the node to a libcall based on first argument type (for instance
@@ -4980,19 +4979,20 @@ void SelectionDAGLegalize::ConvertNodeToLibcall(SDNode *Node) {
RTLIB::MUL_I64, RTLIB::MUL_I128));
break;
case ISD::CTLZ_ZERO_UNDEF:
- switch (Node->getSimpleValueType(0).SimpleTy) {
- default:
- llvm_unreachable("LibCall explicitly requested, but not available");
- case MVT::i32:
- Results.push_back(ExpandLibCall(RTLIB::CTLZ_I32, Node, false).first);
- break;
- case MVT::i64:
- Results.push_back(ExpandLibCall(RTLIB::CTLZ_I64, Node, false).first);
- break;
- case MVT::i128:
- Results.push_back(ExpandLibCall(RTLIB::CTLZ_I128, Node, false).first);
- break;
- }
+ Results.push_back(ExpandIntLibCall(Node, /*IsSigned=*/false,
+ RTLIB::UNKNOWN_LIBCALL,
+ RTLIB::UNKNOWN_LIBCALL,
+ RTLIB::CTLZ_I32,
+ RTLIB::CTLZ_I64,
+ RTLIB::CTLZ_I128));
+ break;
+ case ISD::CTPOP:
+ Results.push_back(ExpandIntLibCall(Node, /*IsSigned=*/false,
+ RTLIB::UNKNOWN_LIBCALL,
+ RTLIB::UNKNOWN_LIBCALL,
+ RTLIB::CTPOP_I32,
+ RTLIB::CTPOP_I64,
+ RTLIB::CTPOP_I128));
break;
case ISD::RESET_FPENV: {
// It is legalized to call 'fesetenv(FE_DFL_ENV)'. On most targets
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
Some in-tree targets (e.g. ARM) could benefit from this lowering, at least in opt-size mode, but I don't know if the libcall is available in their libgcc, so no tests.
e5b5979
to
bb8a735
Compare
Dead code? |
Should be easy to find out? |
Right. It appears it is available and gcc uses it for |
79cb32d
to
66ae5db
Compare
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload | ||
; RV64I-NEXT: addi sp, sp, 16 | ||
; RV64I-NEXT: sext.w a0, a0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
__popcountsi2 should be returning a sign extended result right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nevermind, this is probably a bug specific to rv64-legal-i32 which is still experimental.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried setting IsSExt
to true in MakeLibCallOptions
, but that changed nothing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It appears 32-bit libcall is not available in 64-bit libgcc. I reverted to Expand action for rv64-legal-i32.
ping |
SDValue ExpandIntLibCall(SDNode *Node, bool IsSigned, RTLIB::Libcall Call_I8, | ||
RTLIB::Libcall Call_I16, RTLIB::Libcall Call_I32, | ||
RTLIB::Libcall Call_I64, RTLIB::Libcall Call_I128); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like a lot of unrelated format changes?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I renamed isSigned -> IsSigned while I was here, clang-format insisted that I reformat this code fragment.
Do I need to revert these changes?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, didn't notice the capital letter change. I don't think it's necessary to change then.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can precommit this unrelated change
@topperc |
RISC-V changes look ok. |
This is likely causing armv7/v8 stage2 build failures (other changes don't look related): I don't have an ARM machine handy to investigate, so I'll just revert the ARM changes and see if it helps. |
@antmox should be able to help you figure it out, he's maintaining the bots this week. |
The reversal made the bots green. I think I understood what the issue is. All popcount libcalls returns I'll revert the rest of the patch because the issue should affect RISC-V as well. |
This reverts commit 92e18ff.
) Reverts the rest of #99752
The main change is adding CTPOP to `RuntimeLibcalls.def` to allow targets to use LibCall action for CTPOP. DAG legalizers are changed accordingly.
This is a reland of #99752 with the bug fixed (see test diff in the third commit in this PR). All `popcount` libcalls return `int`, but `ISD::CTPOP` returns the type of the argument, which can be wider than `int`. The fix is to make DAG legalizer pass the correct return type to `makeLibCall` and sign-extend the result afterwards. Original commit message: The main change is adding CTPOP to `RuntimeLibcalls.def` to allow targets to use LibCall action for CTPOP. DAG legalizers are changed accordingly. Pull Request: #101786
This is a reland of llvm#99752 with the bug fixed (see test diff in the third commit in this PR). All `popcount` libcalls return `int`, but `ISD::CTPOP` returns the type of the argument, which can be wider than `int`. The fix is to make DAG legalizer pass the correct return type to `makeLibCall` and sign-extend the result afterwards. Original commit message: The main change is adding CTPOP to `RuntimeLibcalls.def` to allow targets to use LibCall action for CTPOP. DAG legalizers are changed accordingly. Pull Request: llvm#101786
This is a reland of llvm#99752 with the bug fixed (see test diff in the third commit in this PR). All `popcount` libcalls return `int`, but `ISD::CTPOP` returns the type of the argument, which can be wider than `int`. The fix is to make DAG legalizer pass the correct return type to `makeLibCall` and sign-extend the result afterwards. Original commit message: The main change is adding CTPOP to `RuntimeLibcalls.def` to allow targets to use LibCall action for CTPOP. DAG legalizers are changed accordingly. Pull Request: llvm#101786
This is a reland of llvm#99752 with the bug fixed (see test diff in the third commit in this PR). All `popcount` libcalls return `int`, but `ISD::CTPOP` returns the type of the argument, which can be wider than `int`. The fix is to make DAG legalizer pass the correct return type to `makeLibCall` and sign-extend the result afterwards. Original commit message: The main change is adding CTPOP to `RuntimeLibcalls.def` to allow targets to use LibCall action for CTPOP. DAG legalizers are changed accordingly. Pull Request: llvm#101786
The main change is adding CTPOP to
RuntimeLibcalls.def
to allowtargets to use LibCall action for CTPOP. DAG legalizers are changed
accordingly.