This is an archive of the discontinued LLVM Phabricator instance.

[llvm-reduce] Add option to reduce values to zero instead of undef
AbandonedPublic

Authored by aeubanks on Sep 22 2021, 11:16 AM.

Details

Summary

When creating minimal reproducers, having many undefs everywhere is not
ideal. Using zero produces cleaner minimal reproducers.

Diff Detail

Event Timeline

aeubanks requested review of this revision.Sep 22 2021, 11:16 AM
aeubanks created this revision.
Herald added a project: Restricted Project. · View Herald TranscriptSep 22 2021, 11:16 AM
nikic added a comment.Sep 22 2021, 1:54 PM

This looks pretty reasonable to me, but I'm not particularly familiar with llvm-reduce.

I was working on such a change myself.

One remark here: Replacing a pointer by a NULL value can have a similar destructive effects like undef. When replacing an LoadInst or StoreInst address with NULL, it is introducing undefined behaviour where there was none before and make test cases reduced this way useless. Could we also optionally not replace pointers with null values? Similar though might also apply to the divisor of a divide/remainder operation.

I made a delta pass that converts these to function arguments instead and could upstream it.

I was working on such a change myself.

One remark here: Replacing a pointer by a NULL value can have a similar destructive effects like undef. When replacing an LoadInst or StoreInst address with NULL, it is introducing undefined behaviour where there was none before and make test cases reduced this way useless. Could we also optionally not replace pointers with null values? Similar though might also apply to the divisor of a divide/remainder operation.

We can change the reduce operands pass to not reduce those specific operands, although that's orthogonal to this change since this change makes things more defined as null is more defined than undef.

I made a delta pass that converts these to function arguments instead and could upstream it.

Yeah that sounds good. I'm worried that we'll end up creating functions with a ton of arguments, but we can land it and see if anybody complains.
Or do you mean specifically convert load/store pointer operands and div/rem divisor operands to arguments?

aeubanks added a subscriber: swamulism.
fhahn added a comment.Oct 5 2021, 2:26 AM

I was working on such a change myself.

One remark here: Replacing a pointer by a NULL value can have a similar destructive effects like undef. When replacing an LoadInst or StoreInst address with NULL, it is introducing undefined behaviour where there was none before and make test cases reduced this way useless. Could we also optionally not replace pointers with null values? Similar though might also apply to the divisor of a divide/remainder operation.

We can change the reduce operands pass to not reduce those specific operands, although that's orthogonal to this change since this change makes things more defined as null is more defined than undef.

I made a delta pass that converts these to function arguments instead and could upstream it.

Yeah that sounds good. I'm worried that we'll end up creating functions with a ton of arguments, but we can land it and see if anybody complains.
Or do you mean specifically convert load/store pointer operands and div/rem divisor operands to arguments?

@Meinersbur I think it would be great if you could share that patch. I don't think adding arguments is a problem per-se, especially if it is limited to a small set of functions required in the final reproducer. One of the main benefits of replacing undef is reducing new sources of UB, which adding arguments would achieve. There also should be a couple of things we could do to try to keep the number of extra arguments in check, e.g. trying to re-use arguments.

@Meinersbur I think it would be great if you could share that patch. I don't think adding arguments is a problem per-se, especially if it is limited to a small set of functions required in the final reproducer. One of the main benefits of replacing undef is reducing new sources of UB, which adding arguments would achieve. There also should be a couple of things we could do to try to keep the number of extra arguments in check, e.g. trying to re-use arguments.

D111503

I have another pass that "compresses" arguments by reusing other values of the same type s.t. that some become unused and are removed by the argument reduction pass.

@aeubanks Can I have enabled Undef values but reduce to zero constants too, in case Zero still triggers the bug, but not Undef? In my experience, constant one (for integers) also helped reducing further.

What I have been using is a "reduce-to-one", "reduce-to-zero" and "reduce-to-undef" pass. reduce-to-one would not reduce anything that is already one, zero, or undef (to ensure we can reach a fixpoint). reduce-to-zero does not change anything that is already zero or undef. reduce-to-undef can reduce what is not already undef. To not have undef appear in the reduction output, I would just not run the reduce-to-undef pass.

Thoughts?

aeubanks planned changes to this revision.Oct 13 2021, 3:10 PM

@aeubanks Can I have enabled Undef values but reduce to zero constants too, in case Zero still triggers the bug, but not Undef? In my experience, constant one (for integers) also helped reducing further.

What I have been using is a "reduce-to-one", "reduce-to-zero" and "reduce-to-undef" pass. reduce-to-one would not reduce anything that is already one, zero, or undef (to ensure we can reach a fixpoint). reduce-to-zero does not change anything that is already zero or undef. reduce-to-undef can reduce what is not already undef. To not have undef appear in the reduction output, I would just not run the reduce-to-undef pass.

Thoughts?

Specifically for the reduce-operands pass I agree it would be much nicer to attempt to reduce to undef/1/0, probably in that order (so we get as many 0s as possible and as few undefs as possible).

This patch touches more than just reduce-operands though, and now I think in the other passes it probably doesn't matter as much exactly what we reduce things to since we'll clean things up in the reduce-operands pass. So I guess I've talked myself out of this patch.

@aeubanks Can I have enabled Undef values but reduce to zero constants too, in case Zero still triggers the bug, but not Undef? In my experience, constant one (for integers) also helped reducing further.

What I have been using is a "reduce-to-one", "reduce-to-zero" and "reduce-to-undef" pass. reduce-to-one would not reduce anything that is already one, zero, or undef (to ensure we can reach a fixpoint). reduce-to-zero does not change anything that is already zero or undef. reduce-to-undef can reduce what is not already undef. To not have undef appear in the reduction output, I would just not run the reduce-to-undef pass.

Thoughts?

Specifically for the reduce-operands pass I agree it would be much nicer to attempt to reduce to undef/1/0, probably in that order (so we get as many 0s as possible and as few undefs as possible).

This patch touches more than just reduce-operands though, and now I think in the other passes it probably doesn't matter as much exactly what we reduce things to since we'll clean things up in the reduce-operands pass. So I guess I've talked myself out of this patch.

https://reviews.llvm.org/D111765

aeubanks abandoned this revision.Nov 2 2021, 4:49 PM