Diogo Sampaio via llvm-dev
2021-Aug-18 20:45 UTC
[llvm-dev] Canonicalizing conditional loads
Hi, our target machine has conditional (predicated) load instructions. However it is hard to generate at dag-select as clang emits conditional branches to avoid performing the load in most cases. e.g.:https://godbolt.org/z/ohKTnqeqz All these functions perform the same thing, but only the first one does not add a conditional branch instruction. Is there a way to tell clang to always generate the code as the first function, or perhaps a llvm pass that converts the conditional branch/load into a select or hoists the load before/after the branch, also using a select? If not, would anyone else be interested in such thing? Any ideas for which would be the best solution? Regards, Diogo Sampaio
Jason Eckhardt via llvm-dev
2021-Aug-18 23:52 UTC
[llvm-dev] Canonicalizing conditional loads
>Is there a way to tell clang to always generate the code as the first function, or perhaps a llvm pass that converts the conditional branch/load into a select or hoists the load before/after the branch, also using a select?Have you tried enabling either the EarlyIfConverter pass (for selects/conditional-moves) or EarlyIfPredicator pass (for predicated instructions) in the LLVM backend? If you are writing a downstream target, you will need to implement a few TargetInstrInfo APIs to get either pass up and running. Some in-tree backends use the former pass (e.g., AArch64, PPC). I use the latter in a downstream backend with reasonable results. There is also an IR-level speculator in SimplifyCFG that may catch some of your opportunities (see caveats): /// Speculate a conditional basic block flattening the CFG. /// /// Note that this is a very risky transform currently. Speculating /// instructions like this is most often not desirable. Instead, there is an MI /// pass which can do it with full awareness of the resource constraints. /// However, some cases are "obvious" and we should do directly. An example of /// this is speculating a single, reasonably cheap instruction. /// /// There is only one distinct advantage to flattening the CFG at the IR level: /// it makes very common but simplistic optimizations such as are common in /// instcombine and the DAG combiner more powerful by removing CFG edges and /// modeling their effects with easier to reason about SSA value graphs. /// /// /// An illustration of this transform is turning this IR: /// \code /// BB: /// %cmp = icmp ult %x, %y /// br i1 %cmp, label %EndBB, label %ThenBB /// ThenBB: /// %sub = sub %x, %y /// br label BB2 /// EndBB: /// %phi = phi [ %sub, %ThenBB ], [ 0, %EndBB ] /// ... /// \endcode /// /// Into this IR: /// \code /// BB: /// %cmp = icmp ult %x, %y /// %sub = sub %x, %y /// %cond = select i1 %cmp, 0, %sub /// ... /// \endcode /// /// \returns true if the conditional block is removed. bool SimplifyCFGOpt::SpeculativelyExecuteBB(BranchInst *BI, BasicBlock *ThenBB, const TargetTransformInfo ________________________________ From: llvm-dev <llvm-dev-bounces at lists.llvm.org> on behalf of Diogo Sampaio via llvm-dev <llvm-dev at lists.llvm.org> Sent: Wednesday, August 18, 2021 3:45 PM To: cfe-dev at lists.llvm.org <cfe-dev at lists.llvm.org>; llvm-dev <llvm-dev at lists.llvm.org> Subject: [llvm-dev] Canonicalizing conditional loads External email: Use caution opening links or attachments Hi, our target machine has conditional (predicated) load instructions. However it is hard to generate at dag-select as clang emits conditional branches to avoid performing the load in most cases. e.g.:https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgodbolt.org%2Fz%2FohKTnqeqz&data=04%7C01%7Cjeckhardt%40nvidia.com%7C6b309028a3f646dc312c08d962892a54%7C43083d15727340c1b7db39efd9ccc17a%7C0%7C0%7C637649163524599564%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=f9eSwLPRl7pZ1%2FzXAL5i%2B8dzPkwifT9Fk6FvIS7X6WA%3D&reserved=0 All these functions perform the same thing, but only the first one does not add a conditional branch instruction. Is there a way to tell clang to always generate the code as the first function, or perhaps a llvm pass that converts the conditional branch/load into a select or hoists the load before/after the branch, also using a select? If not, would anyone else be interested in such thing? Any ideas for which would be the best solution? Regards, Diogo Sampaio _______________________________________________ LLVM Developers mailing list llvm-dev at lists.llvm.org https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.llvm.org%2Fcgi-bin%2Fmailman%2Flistinfo%2Fllvm-dev&data=04%7C01%7Cjeckhardt%40nvidia.com%7C6b309028a3f646dc312c08d962892a54%7C43083d15727340c1b7db39efd9ccc17a%7C0%7C0%7C637649163524599564%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=Qdl1GdBO9QXdAGG6cQu6kvKRD2WELiVHa9eMIQ4Ubeo%3D&reserved=0 -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20210818/6fddc0e4/attachment.html>