---------------------------------------- define i4 @src(i4 %a, i4 %b, i4 %c) { %or1 = or i4 %b, %a %not1 = xor i4 %or1, -1 %or2 = or i4 %a, %c %not2 = xor i4 %or2, -1 %and = and i4 %not2, %b %or3 = or i4 %and, %not1 ret i4 %or3 } define i4 @tgt(i4 %a, i4 %b, i4 %c) { %and = and i4 %c, %b %or = or i4 %and, %a %or3 = xor i4 %or, -1 ret i4 %or3 } Transformation seems to be correct!
Details
Diff Detail
Event Timeline
Similar feedback as D112276 - more tests needed (8 commutes, extra uses of intermediate values).
llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp | ||
---|---|---|
2800–2801 | This one's a little smaller/easier than the other patch. If we have one-use checks on Op0 (the 'and') and Op1 (the 'not' of RHS), then this transform should be fine. So we don't need the m_OneUse on the inner 'not' here. | |
llvm/test/Transforms/InstCombine/and-xor-or.ll | ||
1105 | Add an instruction to prevent this from commuting. | |
1110 | This is identical to the first test? | |
1167 | Flipped the wrong set of operands? This is effectively the same as "commute2". The final 'or' doesn't really matter (but it's fine to commute that just to be sure). | |
1202 | Add an instruction to prevent this from commuting. |
LGTM.
The commute tests are not complete, but they should be enough to ensure the pattern-matching won't silently break.
llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp | ||
---|---|---|
2822 | The use checks aren't what I suggested, but either way, it is overly conservative (and we would see improvements on some of the tests that are currently left unchanged), so please put a TODO comment on this block to suggest we can loosen the use checks. |
This one's a little smaller/easier than the other patch. If we have one-use checks on Op0 (the 'and') and Op1 (the 'not' of RHS), then this transform should be fine. So we don't need the m_OneUse on the inner 'not' here.