[SDAG] simplify bitwise logic with repeated operand

We do not have general reassociation here (and probably
do not need it), but I noticed these were missing in
patches/tests motivated by D111530, so we can at
least handle the simplest patterns.

The VE test diff looks correct, but we miss that
pattern in IR currently:
https://alive2.llvm.org/ce/z/u66_PM
This commit is contained in:
Sanjay Patel 2022-03-13 11:06:53 -04:00
parent 9f4caf55db
commit c2592c374e
7 changed files with 48 additions and 90 deletions

View File

@ -1075,6 +1075,25 @@ SDValue DAGCombiner::reassociateOpsCommutative(unsigned Opc, const SDLoc &DL,
return SDValue();
}
}
// Check for repeated operand logic simplifications.
if (Opc == ISD::AND || Opc == ISD::OR) {
// (N00 & N01) & N00 --> N00 & N01
// (N00 & N01) & N01 --> N00 & N01
// (N00 | N01) | N00 --> N00 | N01
// (N00 | N01) | N01 --> N00 | N01
if (N1 == N00 || N1 == N01)
return N0;
}
if (Opc == ISD::XOR) {
// (N00 ^ N01) ^ N00 --> N01
if (N1 == N00)
return N01;
// (N00 ^ N01) ^ N01 --> N00
if (N1 == N01)
return N00;
}
return SDValue();
}

View File

@ -4,8 +4,7 @@
define i32 @and_commute0(i32 %x, i32 %y) {
; CHECK-LABEL: and_commute0:
; CHECK: // %bb.0:
; CHECK-NEXT: and w8, w0, w1
; CHECK-NEXT: and w0, w0, w8
; CHECK-NEXT: and w0, w0, w1
; CHECK-NEXT: ret
%b = and i32 %x, %y
%b2 = and i32 %x, %b
@ -15,10 +14,8 @@ define i32 @and_commute0(i32 %x, i32 %y) {
define i128 @and_commute1(i128 %x, i128 %y) {
; CHECK-LABEL: and_commute1:
; CHECK: // %bb.0:
; CHECK-NEXT: and x8, x3, x1
; CHECK-NEXT: and x9, x2, x0
; CHECK-NEXT: and x0, x0, x9
; CHECK-NEXT: and x1, x1, x8
; CHECK-NEXT: and x0, x2, x0
; CHECK-NEXT: and x1, x3, x1
; CHECK-NEXT: ret
%b = and i128 %y, %x
%b2 = and i128 %x, %b
@ -28,8 +25,7 @@ define i128 @and_commute1(i128 %x, i128 %y) {
define <4 x i32> @and_commute2(<4 x i32> %x, <4 x i32> %y) {
; CHECK-LABEL: and_commute2:
; CHECK: // %bb.0:
; CHECK-NEXT: and v1.16b, v0.16b, v1.16b
; CHECK-NEXT: and v0.16b, v1.16b, v0.16b
; CHECK-NEXT: and v0.16b, v0.16b, v1.16b
; CHECK-NEXT: ret
%b = and <4 x i32> %x, %y
%b2 = and <4 x i32> %b, %x
@ -39,7 +35,6 @@ define <4 x i32> @and_commute2(<4 x i32> %x, <4 x i32> %y) {
define <8 x i16> @and_commute3(<8 x i16> %x, <8 x i16> %y) {
; CHECK-LABEL: and_commute3:
; CHECK: // %bb.0:
; CHECK-NEXT: and v1.16b, v1.16b, v0.16b
; CHECK-NEXT: and v0.16b, v1.16b, v0.16b
; CHECK-NEXT: ret
%b = and <8 x i16> %y, %x
@ -50,8 +45,7 @@ define <8 x i16> @and_commute3(<8 x i16> %x, <8 x i16> %y) {
define i16 @or_commute0(i16 %x, i16 %y) {
; CHECK-LABEL: or_commute0:
; CHECK: // %bb.0:
; CHECK-NEXT: orr w8, w0, w1
; CHECK-NEXT: orr w0, w0, w8
; CHECK-NEXT: orr w0, w0, w1
; CHECK-NEXT: ret
%b = or i16 %x, %y
%b2 = or i16 %x, %b
@ -61,8 +55,7 @@ define i16 @or_commute0(i16 %x, i16 %y) {
define i8 @or_commute1(i8 %x, i8 %y) {
; CHECK-LABEL: or_commute1:
; CHECK: // %bb.0:
; CHECK-NEXT: orr w8, w1, w0
; CHECK-NEXT: orr w0, w0, w8
; CHECK-NEXT: orr w0, w1, w0
; CHECK-NEXT: ret
%b = or i8 %y, %x
%b2 = or i8 %x, %b
@ -72,8 +65,7 @@ define i8 @or_commute1(i8 %x, i8 %y) {
define <2 x i64> @or_commute2(<2 x i64> %x, <2 x i64> %y) {
; CHECK-LABEL: or_commute2:
; CHECK: // %bb.0:
; CHECK-NEXT: orr v1.16b, v0.16b, v1.16b
; CHECK-NEXT: orr v0.16b, v1.16b, v0.16b
; CHECK-NEXT: orr v0.16b, v0.16b, v1.16b
; CHECK-NEXT: ret
%b = or <2 x i64> %x, %y
%b2 = or <2 x i64> %b, %x
@ -83,13 +75,9 @@ define <2 x i64> @or_commute2(<2 x i64> %x, <2 x i64> %y) {
define <8 x i64> @or_commute3(<8 x i64> %x, <8 x i64> %y) {
; CHECK-LABEL: or_commute3:
; CHECK: // %bb.0:
; CHECK-NEXT: orr v7.16b, v7.16b, v3.16b
; CHECK-NEXT: orr v6.16b, v6.16b, v2.16b
; CHECK-NEXT: orr v5.16b, v5.16b, v1.16b
; CHECK-NEXT: orr v4.16b, v4.16b, v0.16b
; CHECK-NEXT: orr v2.16b, v6.16b, v2.16b
; CHECK-NEXT: orr v0.16b, v4.16b, v0.16b
; CHECK-NEXT: orr v1.16b, v5.16b, v1.16b
; CHECK-NEXT: orr v2.16b, v6.16b, v2.16b
; CHECK-NEXT: orr v3.16b, v7.16b, v3.16b
; CHECK-NEXT: ret
%b = or <8 x i64> %y, %x
@ -100,8 +88,7 @@ define <8 x i64> @or_commute3(<8 x i64> %x, <8 x i64> %y) {
define <16 x i8> @xor_commute0(<16 x i8> %x, <16 x i8> %y) {
; CHECK-LABEL: xor_commute0:
; CHECK: // %bb.0:
; CHECK-NEXT: eor v1.16b, v0.16b, v1.16b
; CHECK-NEXT: eor v0.16b, v0.16b, v1.16b
; CHECK-NEXT: mov v0.16b, v1.16b
; CHECK-NEXT: ret
%b = xor <16 x i8> %x, %y
%b2 = xor <16 x i8> %x, %b
@ -111,10 +98,8 @@ define <16 x i8> @xor_commute0(<16 x i8> %x, <16 x i8> %y) {
define <8 x i32> @xor_commute1(<8 x i32> %x, <8 x i32> %y) {
; CHECK-LABEL: xor_commute1:
; CHECK: // %bb.0:
; CHECK-NEXT: eor v2.16b, v2.16b, v0.16b
; CHECK-NEXT: eor v3.16b, v3.16b, v1.16b
; CHECK-NEXT: eor v0.16b, v0.16b, v2.16b
; CHECK-NEXT: eor v1.16b, v1.16b, v3.16b
; CHECK-NEXT: mov v1.16b, v3.16b
; CHECK-NEXT: mov v0.16b, v2.16b
; CHECK-NEXT: ret
%b = xor <8 x i32> %y, %x
%b2 = xor <8 x i32> %x, %b
@ -124,8 +109,7 @@ define <8 x i32> @xor_commute1(<8 x i32> %x, <8 x i32> %y) {
define i64 @xor_commute2(i64 %x, i64 %y) {
; CHECK-LABEL: xor_commute2:
; CHECK: // %bb.0:
; CHECK-NEXT: eor x8, x0, x1
; CHECK-NEXT: eor x0, x8, x0
; CHECK-NEXT: mov x0, x1
; CHECK-NEXT: ret
%b = xor i64 %x, %y
%b2 = xor i64 %b, %x
@ -135,10 +119,8 @@ define i64 @xor_commute2(i64 %x, i64 %y) {
define i78 @xor_commute3(i78 %x, i78 %y) {
; CHECK-LABEL: xor_commute3:
; CHECK: // %bb.0:
; CHECK-NEXT: eor x8, x3, x1
; CHECK-NEXT: eor x9, x2, x0
; CHECK-NEXT: eor x0, x9, x0
; CHECK-NEXT: eor x1, x8, x1
; CHECK-NEXT: mov x1, x3
; CHECK-NEXT: mov x0, x2
; CHECK-NEXT: ret
%b = xor i78 %y, %x
%b2 = xor i78 %b, %x

View File

@ -1,3 +1,4 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc < %s -mtriple=ve-unknown-unknown | FileCheck %s
define double @maxf64(double, double) {
@ -182,7 +183,6 @@ define zeroext i1 @maxi1(i1 zeroext, i1 zeroext) {
; CHECK-LABEL: maxi1:
; CHECK: # %bb.0:
; CHECK-NEXT: or %s0, %s0, %s1
; CHECK-NEXT: or %s0, %s1, %s0
; CHECK-NEXT: b.l.t (, %s10)
%3 = xor i1 %1, true
%4 = and i1 %3, %0

View File

@ -5,29 +5,13 @@
define void @PR36250() nounwind {
; X86-LABEL: PR36250:
; X86: # %bb.0:
; X86-NEXT: pushl %esi
; X86-NEXT: movl (%eax), %eax
; X86-NEXT: movl %eax, %ecx
; X86-NEXT: roll %ecx
; X86-NEXT: leal (%eax,%eax), %edx
; X86-NEXT: movl %ecx, %esi
; X86-NEXT: orl %ecx, %esi
; X86-NEXT: orl %ecx, %esi
; X86-NEXT: orl %edx, %esi
; X86-NEXT: orl %eax, %esi
; X86-NEXT: cmpl $0, (%eax)
; X86-NEXT: sete (%eax)
; X86-NEXT: popl %esi
; X86-NEXT: retl
;
; X64-LABEL: PR36250:
; X64: # %bb.0:
; X64-NEXT: movq (%rax), %rax
; X64-NEXT: movq %rax, %rcx
; X64-NEXT: rolq %rcx
; X64-NEXT: leaq (%rax,%rax), %rdx
; X64-NEXT: orq %rcx, %rcx
; X64-NEXT: orq %rdx, %rcx
; X64-NEXT: orq %rax, %rcx
; X64-NEXT: cmpq $0, (%rax)
; X64-NEXT: sete (%rax)
; X64-NEXT: retq
%1 = load i448, i448* undef

View File

@ -43,27 +43,11 @@ define void @foo() {
; 6860-NEXT: .cfi_def_cfa_register %ebp
; 6860-NEXT: andl $-8, %esp
; 6860-NEXT: subl $24, %esp
; 6860-NEXT: movw var_22, %dx
; 6860-NEXT: movzwl var_27, %ecx
; 6860-NEXT: movw %cx, %ax
; 6860-NEXT: xorw %ax, %dx
; 6860-NEXT: # implicit-def: $eax
; 6860-NEXT: movw %dx, %ax
; 6860-NEXT: xorl %ecx, %eax
; 6860-NEXT: # kill: def $ax killed $ax killed $eax
; 6860-NEXT: movzwl %ax, %eax
; 6860-NEXT: movzwl var_22, %eax
; 6860-NEXT: movl %eax, {{[0-9]+}}(%esp)
; 6860-NEXT: movl $0, {{[0-9]+}}(%esp)
; 6860-NEXT: movw var_22, %dx
; 6860-NEXT: movzwl var_27, %eax
; 6860-NEXT: movw %ax, %cx
; 6860-NEXT: xorw %cx, %dx
; 6860-NEXT: # implicit-def: $ecx
; 6860-NEXT: movw %dx, %cx
; 6860-NEXT: xorl %eax, %ecx
; 6860-NEXT: # kill: def $cx killed $cx killed $ecx
; 6860-NEXT: movzwl %cx, %edx
; 6860-NEXT: movb %al, %cl
; 6860-NEXT: movzwl var_22, %edx
; 6860-NEXT: movb var_27, %cl
; 6860-NEXT: addb $30, %cl
; 6860-NEXT: movb %cl, {{[-0-9]+}}(%e{{[sb]}}p) # 1-byte Spill
; 6860-NEXT: xorl %eax, %eax
@ -88,14 +72,10 @@ define void @foo() {
;
; X64-LABEL: foo:
; X64: # %bb.0: # %bb
; X64-NEXT: movzwl var_27(%rip), %ecx
; X64-NEXT: movb var_27(%rip), %cl
; X64-NEXT: movzwl var_22(%rip), %eax
; X64-NEXT: xorw %cx, %ax
; X64-NEXT: xorl %ecx, %eax
; X64-NEXT: movzwl %ax, %eax
; X64-NEXT: movq %rax, -{{[0-9]+}}(%rsp)
; X64-NEXT: addb $30, %cl
; X64-NEXT: # kill: def $cl killed $cl killed $ecx
; X64-NEXT: shrq %cl, %rax
; X64-NEXT: movb %al, (%rax)
; X64-NEXT: retq
@ -109,11 +89,8 @@ define void @foo() {
; 686-NEXT: .cfi_def_cfa_register %ebp
; 686-NEXT: andl $-8, %esp
; 686-NEXT: subl $8, %esp
; 686-NEXT: movzwl var_27, %ecx
; 686-NEXT: movb var_27, %cl
; 686-NEXT: movzwl var_22, %eax
; 686-NEXT: xorw %cx, %ax
; 686-NEXT: xorl %ecx, %eax
; 686-NEXT: movzwl %ax, %eax
; 686-NEXT: movl %eax, (%esp)
; 686-NEXT: movl $0, {{[0-9]+}}(%esp)
; 686-NEXT: addb $30, %cl

View File

@ -8,15 +8,16 @@
define void @pr34127() {
; CHECK-LABEL: pr34127:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movzwl var_3(%rip), %eax
; CHECK-NEXT: movzwl var_13(%rip), %ecx
; CHECK-NEXT: andl %eax, %ecx
; CHECK-NEXT: xorl %edx, %edx
; CHECK-NEXT: andl %eax, %ecx
; CHECK-NEXT: movzwl var_13(%rip), %eax
; CHECK-NEXT: movzwl var_3(%rip), %ecx
; CHECK-NEXT: andw %ax, %cx
; CHECK-NEXT: movzwl %cx, %ecx
; CHECK-NEXT: movl %ecx, -{{[0-9]+}}(%rsp)
; CHECK-NEXT: movzwl var_3(%rip), %ecx
; CHECK-NEXT: xorl %edx, %edx
; CHECK-NEXT: testl %eax, %ecx
; CHECK-NEXT: sete %dl
; CHECK-NEXT: andl %eax, %edx
; CHECK-NEXT: andl %ecx, %edx
; CHECK-NEXT: movq %rdx, var_212(%rip)
; CHECK-NEXT: movw $0, (%rax)
; CHECK-NEXT: retq

View File

@ -367,9 +367,6 @@ define void @ossfuzz34366() {
; X86-NEXT: movl %eax, %ecx
; X86-NEXT: andl $2147483647, %ecx # imm = 0x7FFFFFFF
; X86-NEXT: orl %eax, %ecx
; X86-NEXT: orl %eax, %ecx
; X86-NEXT: orl %eax, %ecx
; X86-NEXT: orl %eax, %ecx
; X86-NEXT: sete (%eax)
; X86-NEXT: retl
;
@ -379,8 +376,6 @@ define void @ossfuzz34366() {
; X64-NEXT: movabsq $9223372036854775807, %rcx # imm = 0x7FFFFFFFFFFFFFFF
; X64-NEXT: andq %rax, %rcx
; X64-NEXT: orq %rax, %rcx
; X64-NEXT: orq %rax, %rcx
; X64-NEXT: orq %rax, %rcx
; X64-NEXT: sete (%rax)
; X64-NEXT: retq
%L10 = load i448, i448* undef, align 4