-
Notifications
You must be signed in to change notification settings - Fork 12k
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
[VPlan] Replace disjoint or with add instead of dropping disjoint. #83821
Changes from all commits
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 |
---|---|---|
|
@@ -1216,6 +1216,23 @@ void VPlanTransforms::dropPoisonGeneratingRecipes( | |
// load/store. If the underlying instruction has poison-generating flags, | ||
// drop them directly. | ||
if (auto *RecWithFlags = dyn_cast<VPRecipeWithIRFlags>(CurRec)) { | ||
VPValue *A, *B; | ||
using namespace llvm::VPlanPatternMatch; | ||
// Dropping disjoint from an OR may yield incorrect results, as some | ||
// analysis may have converted it to an Add implicitly (e.g. SCEV used | ||
// for dependence analysis). Instead, replace it with an equivalent Add. | ||
// This is possible as all users of the disjoint OR only access lanes | ||
// where the operands are disjoint or poison otherwise. | ||
if (match(RecWithFlags, m_Or(m_VPValue(A), m_VPValue(B))) && | ||
RecWithFlags->isDisjoint()) { | ||
VPBuilder Builder(RecWithFlags); | ||
VPInstruction *New = Builder.createOverflowingOp( | ||
Instruction::Add, {A, B}, {false, false}, | ||
RecWithFlags->getDebugLoc()); | ||
RecWithFlags->replaceAllUsesWith(New); | ||
RecWithFlags->eraseFromParent(); | ||
CurRec = New; | ||
} | ||
RecWithFlags->dropPoisonGeneratingFlags(); | ||
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. Should this be in the else branch? 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 should be one of the two:
Makes sense to just have it in the else branch. 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. @fhahn the change was reverted because of the use-after-free above. 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. Missed that this was reverted, recommitted with a fix. |
||
} else { | ||
Instruction *Instr = dyn_cast_or_null<Instruction>( | ||
|
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.
Should this be taken care of by VPRecipeWithIRFlags::dropPoisonGeneratingFlags(), i.e., have it replace the opcode of a disjoint Or with Add?
nit (independent):
collectPoisonGeneratingInstrsInBackwardSlice()
does more than collect Instrs, it also updates them.Should code based on such SCEV expressions be generated (expanded(?)) directly?
(This case is reminiscent of dropping assumptions based on conditions subject to predication.)
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.
Hmmm, it may work if there's no need to directly delete the old recipe, i.e. it will get cleaned up. Let me check.
At the moment, SCEV is only used for analysis of existing IR instructions in this case; switching use SCEV expansion for pointer expressions would probably introduce some other potential issues.