Commit Graph

18 Commits

Author SHA1 Message Date
Roman Lebedev 55430f53f3
[InstCombine] `insertelement` is negatible if both sources are negatible
----------------------------------------
define <2 x i4> @negate_insertelement(<2 x i4> %src, i4 %a, i32 %x, <2 x i4> %b) {
%0:
  %t0 = sub <2 x i4> { 0, 0 }, %src
  %t1 = sub i4 0, %a
  %t2 = insertelement <2 x i4> %t0, i4 %t1, i32 %x
  %t3 = sub <2 x i4> %b, %t2
  ret <2 x i4> %t3
}
=>
define <2 x i4> @negate_insertelement(<2 x i4> %src, i4 %a, i32 %x, <2 x i4> %b) {
%0:
  %t2.neg = insertelement <2 x i4> %src, i4 %a, i32 %x
  %t3 = add <2 x i4> %t2.neg, %b
  ret <2 x i4> %t3
}
Transformation seems to be correct!
2020-05-20 21:44:31 +03:00
Roman Lebedev a6097cebe9
[NFC][InstCombine] Negator: tests for insertelement negation 2020-05-20 21:44:31 +03:00
Roman Lebedev ebed96fdbf
[InstCombine] Negator: `extractelement` is negatible if src is negatible
----------------------------------------
define i4 @negate_extractelement(<2 x i4> %x, i32 %y, i4 %z) {
%0:
  %t0 = sub <2 x i4> { 0, 0 }, %x
  call void @use_v2i4(<2 x i4> %t0)
  %t1 = extractelement <2 x i4> %t0, i32 %y
  %t2 = sub i4 %z, %t1
  ret i4 %t2
}
=>
define i4 @negate_extractelement(<2 x i4> %x, i32 %y, i4 %z) {
%0:
  %t0 = sub <2 x i4> { 0, 0 }, %x
  call void @use_v2i4(<2 x i4> %t0)
  %t1.neg = extractelement <2 x i4> %x, i32 %y
  %t2 = add i4 %t1.neg, %z
  ret i4 %t2
}
Transformation seems to be correct!
2020-05-20 21:44:31 +03:00
Roman Lebedev 952e7106b3
[NFC][InstCombine] Negator: tests for extractelement negation 2020-05-20 21:44:30 +03:00
Roman Lebedev a0004358a8
[InstCombine] Negator: 'or' with no common bits set is just 'add'
In `InstCombiner::visitAdd()`, we have
```
  // A+B --> A|B iff A and B have no bits set in common.
  if (haveNoCommonBitsSet(LHS, RHS, DL, &AC, &I, &DT))
    return BinaryOperator::CreateOr(LHS, RHS);
```
so we should handle such `or`'s here, too.
2020-04-28 19:16:32 +03:00
Roman Lebedev a5f22f2b0e
[NFC][InstCombine] Tests for negation of 'or' with no common bits set 2020-04-28 19:16:31 +03:00
Roman Lebedev 5a159ed2a8
[InstCombine] Negator: don't negate multi-use `sub`
While we can do that, it doesn't increase instruction count,
if the old `sub` sticks around then the transform is not only
not a unlikely win, but a likely regression, since we likely
now extended live range and use count of both of the `sub` operands,
as opposed to just the result of `sub`.

As Kostya Serebryany notes in post-commit review in
https://reviews.llvm.org/D68408#1998112
this indeed can degrade final assembly,
increase register pressure, and spilling.

This isn't what we want here,
so at least for now let's guard it with an use check.
2020-04-23 23:59:15 +03:00
Roman Lebedev a70d2ab323
[NFC][InstCombine] Tests for negation of sign-/zero- extensions
* sext of non-positive can be negated.
* zext of non-negative can be negated.
2020-04-22 17:37:42 +03:00
Roman Lebedev 67266d879c
[InstCombine] Negator: shufflevector is negatible
All these folds are correct as per alive-tv
2020-04-22 15:14:23 +03:00
Roman Lebedev 4d44ce7437
[NFC][InstCombine] Add shuffle negation tests 2020-04-22 15:14:23 +03:00
Roman Lebedev 352fef3f11
[InstCombine] Negator - sink sinkable negations
Summary:
As we have discussed previously (e.g. in D63992 / D64090 / [[ https://bugs.llvm.org/show_bug.cgi?id=42457 | PR42457 ]]), `sub` instruction
can almost be considered non-canonical. While we do convert `sub %x, C` -> `add %x, -C`,
we sparsely do that for non-constants. But we should.

Here, i propose to interpret `sub %x, %y` as `add (sub 0, %y), %x` IFF the negation can be sinked into the `%y`

This has some potential to cause endless combine loops (either around PHI's, or if there are some opposite transforms).
For former there's `-instcombine-negator-max-depth` option to mitigate it, should this expose any such issues
For latter, if there are still any such opposing folds, we'd need to remove the colliding fold.
In any case, reproducers welcomed!

Reviewers: spatel, nikic, efriedma, xbolva00

Reviewed By: spatel

Subscribers: xbolva00, mgorny, hiraditya, reames, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D68408
2020-04-21 22:00:23 +03:00
Roman Lebedev 1f9c169990
[NFC][InstCombine] sub-of-negatible.ll: some more test cases 2020-04-21 20:14:09 +03:00
Sanjay Patel 4036a0af24 [InstCombine] enhance freelyNegateValue() by handling 'not'
This patch extends D77230. If we have a 'not' instruction inside a
negated expression, we can ignore extra uses of that op because the
negation has a one-to-one replacement: negate becomes increment.

Alive2 examples of the test cases:
http://volta.cs.utah.edu:8080/z/T5-u9P
http://volta.cs.utah.edu:8080/z/eT89L6

Differential Revision: https://reviews.llvm.org/D77459
2020-04-05 09:16:19 -04:00
Sanjay Patel b7397e81fe [InstCombine] add tests for freelyNegateValue with 'not'; NFC 2020-04-03 17:28:29 -04:00
Sanjay Patel 3d90048791 [InstCombine] enhance freelyNegateValue() by handling xor
Negation is equivalent to bitwise-not + 1, so try to convert more
subtracts into adds using this relationship:
0 - (A ^ C) => ((A ^ C) ^ -1) + 1 => A ^ ~C + 1

I doubt this will recover the regression noted in rGf2fbdf76d8d0,
but seems like we're going to need to improve here and/or revive D68408?

Alive2 proofs:
http://volta.cs.utah.edu:8080/z/Re5tMU
http://volta.cs.utah.edu:8080/z/An-uns

Differential Revision: https://reviews.llvm.org/D77230
2020-04-01 15:05:13 -04:00
Sanjay Patel 8431dbacd4 [InstCombine] add tests for negate with xor operand; NFC 2020-04-01 15:05:13 -04:00
Roman Lebedev cd04e8349b
[NFC][InstCombine] Update sub-of-negatible.ll test 2019-12-04 15:49:36 +03:00
Roman Lebedev c780645736 [NFC][InstCombine] Some tests for sub-of-negatible pattern
As we have previously estabilished, `sub` is an outcast,
and should be considered non-canonical iff it can be converted to `add`.

It can be converted to `add` if it's second operand can be negated.
So far we mostly only do that for constants and negation itself,
but we should be more through.

llvm-svn: 373597
2019-10-03 13:36:00 +00:00