[llvm] r199976 - [X86] Prevent the creation of redundant ops for sadd and ssub with overflow.
Juergen Ributzka
juergen at apple.com
Thu Jan 23 22:47:57 PST 2014
Author: ributzka
Date: Fri Jan 24 00:47:57 2014
New Revision: 199976
URL: http://llvm.org/viewvc/llvm-project?rev=199976&view=rev
Log:
[X86] Prevent the creation of redundant ops for sadd and ssub with overflow.
This commit teaches the X86 backend to create the same X86 instructions when it
lowers an sadd/ssub with overflow intrinsic and a conditional branch that uses
that overflow result. This allows SelectionDAG to recognize and remove one of
the redundant operations.
This fixes <rdar://problem/15874016> and <rdar://problem/15661073>.
Reviewed by Nadav
Added:
llvm/trunk/test/CodeGen/X86/saddo-redundant-add.ll
Modified:
llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=199976&r1=199975&r2=199976&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Fri Jan 24 00:47:57 2014
@@ -10715,11 +10715,26 @@ SDValue X86TargetLowering::LowerBRCOND(S
unsigned X86Opcode;
unsigned X86Cond;
SDVTList VTs;
+ // Keep this in sync with LowerXALUO, otherwise we might create redundant
+ // instructions that can't be removed afterwards (i.e. X86ISD::ADD and
+ // X86ISD::INC).
switch (CondOpcode) {
case ISD::UADDO: X86Opcode = X86ISD::ADD; X86Cond = X86::COND_B; break;
- case ISD::SADDO: X86Opcode = X86ISD::ADD; X86Cond = X86::COND_O; break;
+ case ISD::SADDO:
+ if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(RHS))
+ if (C->isOne()) {
+ X86Opcode = X86ISD::INC; X86Cond = X86::COND_O;
+ break;
+ }
+ X86Opcode = X86ISD::ADD; X86Cond = X86::COND_O; break;
case ISD::USUBO: X86Opcode = X86ISD::SUB; X86Cond = X86::COND_B; break;
- case ISD::SSUBO: X86Opcode = X86ISD::SUB; X86Cond = X86::COND_O; break;
+ case ISD::SSUBO:
+ if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(RHS))
+ if (C->isOne()) {
+ X86Opcode = X86ISD::DEC; X86Cond = X86::COND_O;
+ break;
+ }
+ X86Opcode = X86ISD::SUB; X86Cond = X86::COND_O; break;
case ISD::UMULO: X86Opcode = X86ISD::UMUL; X86Cond = X86::COND_O; break;
case ISD::SMULO: X86Opcode = X86ISD::SMUL; X86Cond = X86::COND_O; break;
default: llvm_unreachable("unexpected overflowing operator");
Added: llvm/trunk/test/CodeGen/X86/saddo-redundant-add.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/saddo-redundant-add.ll?rev=199976&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/saddo-redundant-add.ll (added)
+++ llvm/trunk/test/CodeGen/X86/saddo-redundant-add.ll Fri Jan 24 00:47:57 2014
@@ -0,0 +1,34 @@
+; RUN: llc < %s -mtriple=x86_64-apple-darwin | FileCheck %s
+
+define void @redundant_add(i64 %n) {
+; Check that we don't create two additions for the sadd.with.overflow.
+; CHECK-LABEL: redundant_add
+; CHECK-NOT: leaq
+; CHECK-NOT: addq
+; CHECK: incq
+; CHECK-NEXT: jno
+entry:
+ br label %exit_check
+
+exit_check:
+ %i = phi i64 [ 0, %entry ], [ %i.next, %loop ]
+ %c = icmp slt i64 %i, %n
+ br i1 %c, label %loop, label %exit
+
+loop:
+ %i.o = tail call { i64, i1 } @llvm.sadd.with.overflow.i64(i64 %i, i64 1)
+ %i.next = extractvalue { i64, i1 } %i.o, 0
+ %o = extractvalue { i64, i1 } %i.o, 1
+ br i1 %o, label %overflow, label %exit_check
+
+exit:
+ ret void
+
+overflow:
+ tail call void @llvm.trap()
+ unreachable
+}
+
+declare { i64, i1 } @llvm.sadd.with.overflow.i64(i64, i64)
+declare void @llvm.trap()
+
More information about the llvm-commits
mailing list