forked from OSchip/llvm-project
[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:
parent
9f4caf55db
commit
c2592c374e
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue