[X86] Add RMW ADC patterns with load in operand 1.

ADC is commutable and the load could be in either operand, but we were only checking operand 0.

Ideally we'd mark X86adc_flag as commutable and tablegen would automatically do this, but the EFLAGS register mention is preventing it.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@341606 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Craig Topper 2018-09-06 23:55:36 +00:00
parent 68e835e9f0
commit 70e99b3383
2 changed files with 23 additions and 10 deletions

View File

@ -1178,14 +1178,28 @@ defm CMP : ArithBinOp_F<0x38, 0x3A, 0x3C, "cmp", MRM7r, MRM7m, X86cmp, 0, 0>;
// Patterns to recognize loads on the LHS of an ADC. We can't make X86adc_flag
// commutable since it has EFLAGs as an input.
def : Pat<(X86adc_flag (loadi8 addr:$src1), GR8:$src2, EFLAGS),
(ADC8rm GR8:$src2, addr:$src1)>;
def : Pat<(X86adc_flag (loadi16 addr:$src1), GR16:$src2, EFLAGS),
(ADC16rm GR16:$src2, addr:$src1)>;
def : Pat<(X86adc_flag (loadi32 addr:$src1), GR32:$src2, EFLAGS),
(ADC32rm GR32:$src2, addr:$src1)>;
def : Pat<(X86adc_flag (loadi64 addr:$src1), GR64:$src2, EFLAGS),
(ADC64rm GR64:$src2, addr:$src1)>;
def : Pat<(X86adc_flag (loadi8 addr:$src2), GR8:$src1, EFLAGS),
(ADC8rm GR8:$src1, addr:$src2)>;
def : Pat<(X86adc_flag (loadi16 addr:$src2), GR16:$src1, EFLAGS),
(ADC16rm GR16:$src1, addr:$src2)>;
def : Pat<(X86adc_flag (loadi32 addr:$src2), GR32:$src1, EFLAGS),
(ADC32rm GR32:$src1, addr:$src2)>;
def : Pat<(X86adc_flag (loadi64 addr:$src2), GR64:$src1, EFLAGS),
(ADC64rm GR64:$src1, addr:$src2)>;
// Patterns to recognize RMW ADC with loads in operand 1.
def : Pat<(store (X86adc_flag GR8:$src, (loadi8 addr:$dst), EFLAGS),
addr:$dst),
(ADC8mr addr:$dst, GR8:$src)>;
def : Pat<(store (X86adc_flag GR16:$src, (loadi16 addr:$dst), EFLAGS),
addr:$dst),
(ADC16mr addr:$dst, GR16:$src)>;
def : Pat<(store (X86adc_flag GR32:$src, (loadi32 addr:$dst), EFLAGS),
addr:$dst),
(ADC32mr addr:$dst, GR32:$src)>;
def : Pat<(store (X86adc_flag GR64:$src, (loadi64 addr:$dst), EFLAGS),
addr:$dst),
(ADC64mr addr:$dst, GR64:$src)>;
//===----------------------------------------------------------------------===//
// Semantically, test instructions are similar like AND, except they don't

View File

@ -31,9 +31,8 @@ define void @add128_rmw2(i128 %a, i128* %b) nounwind {
; CHECK-LABEL: add128_rmw2:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: addq (%rdx), %rdi
; CHECK-NEXT: adcq 8(%rdx), %rsi
; CHECK-NEXT: adcq %rsi, 8(%rdx)
; CHECK-NEXT: movq %rdi, (%rdx)
; CHECK-NEXT: movq %rsi, 8(%rdx)
; CHECK-NEXT: retq
entry:
%0 = load i128, i128* %b