1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 12:41:49 +01:00

[NFC][InstCombine] '(Op1 & С) - Op1' -> '-(Op1 & ~C)' fold (PR44427)

This decreases use count of Op1, potentially allows
us to further hoist said 'neg' later on,
and results in marginally better X86 codegen.

Name: (Op1 & С) - Op1 -> -(Op1 & ~C)
  %o = and i64 %Op1, C1
  %r = sub i64 %o, %Op1
=>
  %n = and i64 %Op1, ~C1
  %r = sub i64 0, %n

https://rise4fun.com/Alive/rwgA

https://godbolt.org/z/R_RMfM

https://bugs.llvm.org/show_bug.cgi?id=44427
This commit is contained in:
Roman Lebedev 2020-01-03 21:10:51 +03:00
parent c8e63d2baa
commit a4fc069a94
3 changed files with 19 additions and 10 deletions

View File

@ -1889,6 +1889,15 @@ Instruction *InstCombiner::visitSub(BinaryOperator &I) {
}
}
{
// (sub (and Op1, C), Op1) --> neg (and Op1, ~C)
Constant *C;
if (match(Op0, m_OneUse(m_And(m_Specific(Op1), m_Constant(C))))) {
return BinaryOperator::CreateNeg(
Builder.CreateAnd(Op1, Builder.CreateNot(C)));
}
}
if (Op1->hasOneUse()) {
Value *X = nullptr, *Y = nullptr, *Z = nullptr;
Constant *C = nullptr;

View File

@ -84,8 +84,8 @@ define <2 x i64> @test9vec(<2 x i64> %x) {
define i64 @test10(i64 %x) {
; CHECK-LABEL: @test10(
; CHECK-NEXT: [[AND:%.*]] = and i64 [[X:%.*]], 1
; CHECK-NEXT: [[ADD:%.*]] = sub i64 [[AND]], [[X]]
; CHECK-NEXT: [[TMP1:%.*]] = and i64 [[X:%.*]], -2
; CHECK-NEXT: [[ADD:%.*]] = sub i64 0, [[TMP1]]
; CHECK-NEXT: ret i64 [[ADD]]
;
%sub = sub nsw i64 0, %x

View File

@ -15,8 +15,8 @@
define i8 @t0(i8 %x) {
; CHECK-LABEL: @t0(
; CHECK-NEXT: [[UNBIASEDX:%.*]] = and i8 [[X:%.*]], 42
; CHECK-NEXT: [[NEGBIAS:%.*]] = sub i8 [[UNBIASEDX]], [[X]]
; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], -43
; CHECK-NEXT: [[NEGBIAS:%.*]] = sub i8 0, [[TMP1]]
; CHECK-NEXT: ret i8 [[NEGBIAS]]
;
%unbiasedx = and i8 %x, 42
@ -26,8 +26,8 @@ define i8 @t0(i8 %x) {
define <2 x i8> @t1_vec(<2 x i8> %x) {
; CHECK-LABEL: @t1_vec(
; CHECK-NEXT: [[UNBIASEDX:%.*]] = and <2 x i8> [[X:%.*]], <i8 42, i8 42>
; CHECK-NEXT: [[NEGBIAS:%.*]] = sub <2 x i8> [[UNBIASEDX]], [[X]]
; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[X:%.*]], <i8 -43, i8 -43>
; CHECK-NEXT: [[NEGBIAS:%.*]] = sub <2 x i8> zeroinitializer, [[TMP1]]
; CHECK-NEXT: ret <2 x i8> [[NEGBIAS]]
;
%unbiasedx = and <2 x i8> %x, <i8 42, i8 42>
@ -37,8 +37,8 @@ define <2 x i8> @t1_vec(<2 x i8> %x) {
define <2 x i8> @t2_vec_undef(<2 x i8> %x) {
; CHECK-LABEL: @t2_vec_undef(
; CHECK-NEXT: [[UNBIASEDX:%.*]] = and <2 x i8> [[X:%.*]], <i8 42, i8 undef>
; CHECK-NEXT: [[NEGBIAS:%.*]] = sub <2 x i8> [[UNBIASEDX]], [[X]]
; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[X:%.*]], <i8 -43, i8 undef>
; CHECK-NEXT: [[NEGBIAS:%.*]] = sub <2 x i8> zeroinitializer, [[TMP1]]
; CHECK-NEXT: ret <2 x i8> [[NEGBIAS]]
;
%unbiasedx = and <2 x i8> %x, <i8 42, i8 undef>
@ -48,8 +48,8 @@ define <2 x i8> @t2_vec_undef(<2 x i8> %x) {
define <2 x i8> @t3_vec_nonsplat(<2 x i8> %x) {
; CHECK-LABEL: @t3_vec_nonsplat(
; CHECK-NEXT: [[UNBIASEDX:%.*]] = and <2 x i8> [[X:%.*]], <i8 42, i8 44>
; CHECK-NEXT: [[NEGBIAS:%.*]] = sub <2 x i8> [[UNBIASEDX]], [[X]]
; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[X:%.*]], <i8 -43, i8 -45>
; CHECK-NEXT: [[NEGBIAS:%.*]] = sub <2 x i8> zeroinitializer, [[TMP1]]
; CHECK-NEXT: ret <2 x i8> [[NEGBIAS]]
;
%unbiasedx = and <2 x i8> %x, <i8 42, i8 44>