[X86] Add RMW ADC patterns with load in operand 1.
authorCraig Topper <craig.topper@intel.com>
Thu, 6 Sep 2018 23:55:36 +0000 (23:55 +0000)
committerCraig Topper <craig.topper@intel.com>
Thu, 6 Sep 2018 23:55:36 +0000 (23:55 +0000)
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.

llvm-svn: 341606

llvm/lib/Target/X86/X86InstrArithmetic.td
llvm/test/CodeGen/X86/addcarry.ll

index 9df5d76..b38d71a 100644 (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
index 3f9391c..159da9b 100644 (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