Skip to content

Commit e654785

Browse files
committed
[x86] try harder to form LEA from ADD to avoid flag conflicts (PR40483)
LEA doesn't affect flags, so use it more liberally to replace an ADD when we know that the ADD operands affect flags. In the motivating example from PR40483: https://bugs.llvm.org/show_bug.cgi?id=40483 ...this lets us avoid duplicating a math op just to avoid flag conflict. As mentioned in the TODO comments, this heuristic can be extended to fire more often if that leads to more improvements. Differential Revision: https://reviews.llvm.org/D64707 llvm-svn: 366431
1 parent 37d7cb2 commit e654785

File tree

2 files changed

+41
-20
lines changed

2 files changed

+41
-20
lines changed

llvm/lib/Target/X86/X86ISelDAGToDAG.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2464,6 +2464,37 @@ bool X86DAGToDAGISel::selectLEAAddr(SDValue N,
24642464
Complexity += 2;
24652465
}
24662466

2467+
// Heuristic: try harder to form an LEA from ADD if the operands set flags.
2468+
// Unlike ADD, LEA does not affect flags, so we will be less likely to require
2469+
// duplicating flag-producing instructions later in the pipeline.
2470+
if (N.getOpcode() == ISD::ADD) {
2471+
auto isMathWithFlags = [](SDValue V) {
2472+
switch (V.getOpcode()) {
2473+
case X86ISD::ADD:
2474+
case X86ISD::SUB:
2475+
case X86ISD::ADC:
2476+
case X86ISD::SBB:
2477+
/* TODO: These opcodes can be added safely, but we may want to justify
2478+
their inclusion for different reasons (better for reg-alloc).
2479+
case X86ISD::SMUL:
2480+
case X86ISD::UMUL:
2481+
case X86ISD::OR:
2482+
case X86ISD::XOR:
2483+
case X86ISD::AND:
2484+
*/
2485+
// Value 1 is the flag output of the node - verify it's not dead.
2486+
return !SDValue(V.getNode(), 1).use_empty();
2487+
default:
2488+
return false;
2489+
}
2490+
};
2491+
// TODO: This could be an 'or' rather than 'and' to make the transform more
2492+
// likely to happen. We might want to factor in whether there's a
2493+
// load folding opportunity for the math op that disappears with LEA.
2494+
if (isMathWithFlags(N.getOperand(0)) && isMathWithFlags(N.getOperand(1)))
2495+
Complexity++;
2496+
}
2497+
24672498
if (AM.Disp)
24682499
Complexity++;
24692500

llvm/test/CodeGen/X86/combine-sbb.ll

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -309,35 +309,25 @@ define i32 @PR40483_sub5(i32*, i32) nounwind {
309309
define i32 @PR40483_sub6(i32*, i32) nounwind {
310310
; X86-LABEL: PR40483_sub6:
311311
; X86: # %bb.0:
312-
; X86-NEXT: pushl %edi
313-
; X86-NEXT: pushl %esi
314312
; X86-NEXT: movl {{[0-9]+}}(%esp), %edx
315-
; X86-NEXT: movl (%edx), %esi
316-
; X86-NEXT: movl {{[0-9]+}}(%esp), %edi
317-
; X86-NEXT: movl %esi, %ecx
318-
; X86-NEXT: subl %edi, %ecx
313+
; X86-NEXT: movl (%edx), %ecx
319314
; X86-NEXT: xorl %eax, %eax
320-
; X86-NEXT: subl %edi, %esi
321-
; X86-NEXT: movl %esi, (%edx)
315+
; X86-NEXT: subl {{[0-9]+}}(%esp), %ecx
316+
; X86-NEXT: movl %ecx, (%edx)
322317
; X86-NEXT: jae .LBB8_2
323318
; X86-NEXT: # %bb.1:
324-
; X86-NEXT: addl %ecx, %ecx
325-
; X86-NEXT: movl %ecx, %eax
319+
; X86-NEXT: leal (%ecx,%ecx), %eax
326320
; X86-NEXT: .LBB8_2:
327-
; X86-NEXT: popl %esi
328-
; X86-NEXT: popl %edi
329321
; X86-NEXT: retl
330322
;
331323
; X64-LABEL: PR40483_sub6:
332324
; X64: # %bb.0:
333-
; X64-NEXT: movl (%rdi), %ecx
334-
; X64-NEXT: movl %ecx, %edx
335-
; X64-NEXT: subl %esi, %edx
336-
; X64-NEXT: addl %edx, %edx
337-
; X64-NEXT: xorl %eax, %eax
338-
; X64-NEXT: subl %esi, %ecx
339-
; X64-NEXT: movl %ecx, (%rdi)
340-
; X64-NEXT: cmovbl %edx, %eax
325+
; X64-NEXT: movl (%rdi), %eax
326+
; X64-NEXT: xorl %ecx, %ecx
327+
; X64-NEXT: subl %esi, %eax
328+
; X64-NEXT: movl %eax, (%rdi)
329+
; X64-NEXT: leal (%rax,%rax), %eax
330+
; X64-NEXT: cmovael %ecx, %eax
341331
; X64-NEXT: retq
342332
%3 = load i32, i32* %0, align 8
343333
%4 = tail call { i8, i32 } @llvm.x86.subborrow.32(i8 0, i32 %3, i32 %1)

0 commit comments

Comments
 (0)