diff options
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/lib/Target/X86/X86InstrArithmetic.td | 30 | ||||
| -rw-r--r-- | llvm/test/CodeGen/X86/addcarry.ll | 3 |
2 files changed, 23 insertions, 10 deletions
diff --git a/llvm/lib/Target/X86/X86InstrArithmetic.td b/llvm/lib/Target/X86/X86InstrArithmetic.td index 9df5d76c724..b38d71a62c3 100644 --- a/llvm/lib/Target/X86/X86InstrArithmetic.td +++ b/llvm/lib/Target/X86/X86InstrArithmetic.td @@ -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 diff --git a/llvm/test/CodeGen/X86/addcarry.ll b/llvm/test/CodeGen/X86/addcarry.ll index 3f9391c917b..159da9b1928 100644 --- a/llvm/test/CodeGen/X86/addcarry.ll +++ b/llvm/test/CodeGen/X86/addcarry.ll @@ -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 |

