summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/lib/Target/X86/X86InstrArithmetic.td30
-rw-r--r--llvm/test/CodeGen/X86/addcarry.ll3
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
OpenPOWER on IntegriCloud