This is an archive of the discontinued LLVM Phabricator instance.

[IR] Change the default value of InstertElement to poison (1/4)
ClosedPublic

Authored by hyeongyukim on Sep 22 2021, 11:55 PM.

Details

Summary

This patch is for fixing potential insertElement-related bugs like D93818.

V = UndefValue::get(VecTy);
for(...)
  V = Builder.CreateInsertElementy(V, Elt, Idx);
=>
V = PoisonValue::get(VecTy);
for(...)
  V = Builder.CreateInsertElementy(V, Elt, Idx);

Like above, this patch changes the placeholder V to poison.
The patch will be separated into several commits.

Diff Detail

Event Timeline

hyeongyukim created this revision.Sep 22 2021, 11:55 PM
hyeongyukim requested review of this revision.Sep 22 2021, 11:55 PM
Herald added a project: Restricted Project. · View Herald TranscriptSep 22 2021, 11:55 PM
hyeongyukim edited the summary of this revision. (Show Details)Sep 22 2021, 11:56 PM

Like D110226, D110227, and D110230, It would be better to change undef to poison in one place.

Value *CreateInsertElement(Type *VecTy, Value *NewElt, Value *Idx,
                            const Twine &Name = "") {
   return CreateInsertElement(PoisonValue::get(VecTy), NewElt, Idx, Name);
 }

 Value *CreateInsertElement(Type *VecTy, Value *NewElt, uint64_t Idx,
                            const Twine &Name = "") {
   return CreateInsertElement(PoisonValue::get(VecTy), NewElt, Idx, Name);
 }

@spatel How about adding these two functions, which makes an empty placeholder for InsertElement?

I left comments on a few changes - I think it is okay to leave ones that are clearly valid if you prefer.

Q: Is there any test that is affected by this?

Like D110226, D110227, and D110230, It would be better to change undef to poison in one place.

Value *CreateInsertElement(Type *VecTy, Value *NewElt, Value *Idx,
                            const Twine &Name = "") {
   return CreateInsertElement(PoisonValue::get(VecTy), NewElt, Idx, Name);
 }

 Value *CreateInsertElement(Type *VecTy, Value *NewElt, uint64_t Idx,
                            const Twine &Name = "") {
   return CreateInsertElement(PoisonValue::get(VecTy), NewElt, Idx, Name);
 }

I have no preference between adding new ones or explicitly using poison.

llvm/lib/IR/AutoUpgrade.cpp
2420

This change is fine because the for loop below fully hides this value, am I correct?

llvm/lib/Target/NVPTX/NVPTXGenericToNVVM.cpp
215

Is this poison always hidden behind the newly created insertelements below?
In other words, is it possible for this patch to cause a transformation like
<undef, 1, 2> => <poison, mapped(1), mapped(2)>?

llvm/lib/Target/PowerPC/PPCTargetTransformInfo.cpp
136 ↗(On Diff #374452)

I'm not sure about the validity of this change; could you explain the context a bit, please?

Matt added a subscriber: Matt.Sep 26 2021, 2:51 AM

Q: Is there any test that is affected by this?

No, tests were not changed by this patch.

This patch is changing the InsertElement's placeholder to poison without changing the LLVM's behavior.
Detailed information on why InsertElement's placeholder should be changed from noundef to poison can be found at https://bugs.llvm.org/show_bug.cgi?id=44185.

Even though this patch is not changing LLVM's behavior, I expect the vector's initialization will be more consistent.

llvm/lib/IR/AutoUpgrade.cpp
2420

Right, other values are always cover the poisons.
Rep is declared as <Elnum x EltTy> poison, and for loop is filling Rep with a new value from the 0th position to the EltNum-1th position. Therefore, all poison in Rep is changed to different values.
Since noundef has not been created before, this patch neither changes the noundef to poison nor makes a new poison.

llvm/lib/Target/NVPTX/NVPTXGenericToNVVM.cpp
215

Whether C is a ConstantVector or a ConstantAggregate, the noundef is not changed to poison.
Like the function UpgradeIntrinsicCall above, all poisons in NewValue are replaced with NewOperand since the for loop is growing 0 to OperandNum-1. So all poisons of NewValue will be removed.
Also, since all NewOperandes are made through recursive function calls, undef is not changed to poison even inside NewOperands.

Even in this case, there is no change in the operation before and after the patch.

llvm/lib/Target/PowerPC/PPCTargetTransformInfo.cpp
136 ↗(On Diff #374452)

I can't figure out the exact context either.
It is hard to ensure that there are no changes in LLVM before and after this patch, I will revert this part.

Revert PPCTargetTransformInfo.cpp

Like D110226, D110227, and D110230, It would be better to change undef to poison in one place.

Value *CreateInsertElement(Type *VecTy, Value *NewElt, Value *Idx,
                            const Twine &Name = "") {
   return CreateInsertElement(PoisonValue::get(VecTy), NewElt, Idx, Name);
 }

 Value *CreateInsertElement(Type *VecTy, Value *NewElt, uint64_t Idx,
                            const Twine &Name = "") {
   return CreateInsertElement(PoisonValue::get(VecTy), NewElt, Idx, Name);
 }

@spatel How about adding these two functions, which makes an empty placeholder for InsertElement?

Sure - that lines up with the similar create/constructors that we added for shuffles, so it makes things symmetric (even if we don't have too many uses for it currently).
@aqjune - sorry for losing track of D93817 / D94380 . If the newer patches are as you expected, feel free to approve (no need to wait for me).

@spatel Thanks!
@hyeongyukim Do you mind if we add the new CreateInsertElements and use them in this patch?

@spatel Thanks!
@hyeongyukim Do you mind if we add the new CreateInsertElements and use them in this patch?

Of course not, I'll add them. Thanks!

Add the new CreateInsertElement

reformat code

aqjune accepted this revision.Sep 28 2021, 2:29 AM

LGTM

This revision is now accepted and ready to land.Sep 28 2021, 2:29 AM
This revision was landed with ongoing or failed builds.Sep 28 2021, 6:29 AM
This revision was automatically updated to reflect the committed changes.