This patch adds VPValue version of the instruction operands to
VPWidenRecipe and uses them during code-generation.
Similar to D76373 this reduces ingredient def-use usage by ILV as
a step towards full VPlan-based def-use relations.
Differential D76992
[VPlan] Add & use VPValue operands for VPWidenRecipe (NFC). fhahn on Mar 28 2020, 11:19 AM. Authored by
Details This patch adds VPValue version of the instruction operands to Similar to D76373 this reduces ingredient def-use usage by ILV as
Diff Detail
Event TimelineComment Actions Thanks for following-up quickly. The part that extends VPWidenRecipe to have a User for holding its VPValue operands looks ok, but could the patch make sure that these operands are indeed used correctly by ILV::widenInstruction(), instead of moving the latter over to its execute()? The former may involve refactoring the case that deals with Calls, to record cost-based UseVectorInstrinsic/NeedToScalarize decisions when constructing the VPlan/recipe rather than during codegen; to record InvariantCond of Selects instead of accessing getSCEV(I.getOperand(0)) during codegen, possibly cleaning up to generate ScalarCond OR Cond but not both. In any case, accesses to I’s operands should all change to access User's operands instead, possibly with their underlying ingredient if needed. This follows the changes D70865 made to ILV::vectorizeInterleaveGroup() and ILV::vectorizeMemoryInstruction(), focusing only on transforming the def/use relations between recipes, as a first (or in this case second ;-) separate step.
Comment Actions The main reason for moving it into the recipe is so we can use getUnderlyingValue when lowering calls. A cleaner solution to deal with call would be to move them to their own recipe/instruction and record the required info as suggested. Is that along the line you suggest? I.e. something like the following: Move calls to their own recipe (NFC) and then move VPWidenRecipe and VPCallRecipe to VPUser in parallel? Without changes to the call handling, I am not sure how we would be able to use the existing logic (unless we expose getUnderlyingValue to ILV.
Comment Actions Yes, let's go for this cleaner solution. The first phase of VPlan integration using recipes is focused on refactoring ILV logic so that decisions are made and recorded in VPlan rather than during codegen. The latter, taken care of by recipe::execute(), should be as straightforward as possible. Comment Actions I've updated the code to just change how operands are accessed during ILV::widenInstruction. Instead of accessing the operands via the instruction, GetUnderlyingValue/GetScalarValue/GetVectorValue are provided, which use the VPUser & VPTransformState. Call handling was moved to a separate recipe D77467. Comment Actions Pass VPUser and VPTransformState to widenInstruction, instead of accessor callbacks. A callback is still needed to access the underlying value for checking whether the condition is loop-invariant. But I do not think there's a way around that without additional refactoring.
Comment Actions Thanks Gil! I missed the comment in the previous update (sorry!), but I'll add it in the commit.
Comment Actions @fhahn, we also had a crash downstream on our fuzzer run, if you still need a reproducer I can try reducing our failure. Comment Actions Thanks, I've already have a very reduced reproducer, which I'll add when I recommit this patch. Ayal posted a fix for the actual issue (D78847) But it would be great if you could share the unreduced reproducer, to verify it is the same issue.
Comment Actions
This is our original reproducer: Fails on commit 9245c7ac13480ed48ae339ad0e68cbe680cd0642 like this: ] bin/opt -loop-vectorize before-vectorize.ll 2>&1 | c++filt | head -n 12 PLEASE submit a bug report to https://bugs.llvm.org/ and include the crash backtrace. Stack dump: 0. Program arguments: bin/opt -loop-vectorize before-vectorize.ll 1. Running pass 'Function Pass Manager' on module 'before-vectorize.ll'. 2. Running pass 'Loop Vectorization' on function '@"virtual void Test.vMeth1(jint)527365"' /ws/llvm-upstream/builds/release-assert/bin/../lib/libLLVM-11git.so(llvm::sys::PrintStackTrace(llvm::raw_ostream&)+0x1a)[0x7ff9600e0ada] /ws/llvm-upstream/builds/release-assert/bin/../lib/libLLVM-11git.so(llvm::sys::RunSignalHandlers()+0x34)[0x7ff9600deb44] /ws/llvm-upstream/builds/release-assert/bin/../lib/libLLVM-11git.so(+0x72ec83)[0x7ff9600dec83] /lib64/libpthread.so.0(+0xf5d0)[0x7ff95f7a35d0] /ws/llvm-upstream/builds/release-assert/bin/../lib/libLLVM-11git.so(llvm::InnerLoopVectorizer::getBroadcastInstrs(llvm::Value*)+0x10)[0x7ff9611cddb0] /ws/llvm-upstream/builds/release-assert/bin/../lib/libLLVM-11git.so(llvm::InnerLoopVectorizer::getOrCreateVectorValue(llvm::Value*, unsigned int)+0xce)[0x7ff9611db3ee] /ws/llvm-upstream/builds/release-assert/bin/../lib/libLLVM-11git.so(+0x1832361)[0x7ff9611e2361] Comment Actions Recommitted with a reduced version of the reproducer. Both the reproducers don't crash after a3c964a278b4. |
clang-format not found in user's PATH; not linting file.