From 0980ef248e4a20846563da36bfcaa0c58b0cf609 Mon Sep 17 00:00:00 2001 From: Juergen Ributzka Date: Fri, 8 Aug 2014 18:47:04 +0000 Subject: [PATCH] [FastISel][X86] Fix INC/DEC optimization (r215230) I accidentally also used INC/DEC for unsigned arithmetic which doesn't work, because INC/DEC don't set the required flag which is used for the overflow check. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@215237 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/X86FastISel.cpp | 2 +- test/CodeGen/X86/xaluo.ll | 47 ++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/lib/Target/X86/X86FastISel.cpp b/lib/Target/X86/X86FastISel.cpp index 9563db7e450..db3a4fdc9cc 100644 --- a/lib/Target/X86/X86FastISel.cpp +++ b/lib/Target/X86/X86FastISel.cpp @@ -2410,7 +2410,7 @@ bool X86FastISel::FastLowerIntrinsicCall(const IntrinsicInst *II) { { X86::DEC8r, X86::DEC64_16r, X86::DEC64_32r, X86::DEC64r } } }; - if (UseIncDec) { + if (BaseOpc == X86ISD::INC || BaseOpc == X86ISD::DEC) { ResultReg = createResultReg(TLI.getRegClassFor(VT)); bool Is64Bit = Subtarget->is64Bit(); bool IsDec = BaseOpc == X86ISD::DEC; diff --git a/test/CodeGen/X86/xaluo.ll b/test/CodeGen/X86/xaluo.ll index 5e6cd25aded..bc1d0ce77c6 100644 --- a/test/CodeGen/X86/xaluo.ll +++ b/test/CodeGen/X86/xaluo.ll @@ -231,6 +231,51 @@ entry: ret i1 %obit } +; UADDO reg, 1 | NOT INC +define zeroext i1 @uaddo.inc.i8(i8 %v1, i8* %res) { +entry: +; CHECK-LABEL: uaddo.inc.i8 +; CHECK-NOT: incb %dil + %t = call {i8, i1} @llvm.uadd.with.overflow.i8(i8 %v1, i8 1) + %val = extractvalue {i8, i1} %t, 0 + %obit = extractvalue {i8, i1} %t, 1 + store i8 %val, i8* %res + ret i1 %obit +} + +define zeroext i1 @uaddo.inc.i16(i16 %v1, i16* %res) { +entry: +; CHECK-LABEL: uaddo.inc.i16 +; CHECK-NOT: incw %di + %t = call {i16, i1} @llvm.uadd.with.overflow.i16(i16 %v1, i16 1) + %val = extractvalue {i16, i1} %t, 0 + %obit = extractvalue {i16, i1} %t, 1 + store i16 %val, i16* %res + ret i1 %obit +} + +define zeroext i1 @uaddo.inc.i32(i32 %v1, i32* %res) { +entry: +; CHECK-LABEL: uaddo.inc.i32 +; CHECK-NOT: incl %edi + %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 1) + %val = extractvalue {i32, i1} %t, 0 + %obit = extractvalue {i32, i1} %t, 1 + store i32 %val, i32* %res + ret i1 %obit +} + +define zeroext i1 @uaddo.inc.i64(i64 %v1, i64* %res) { +entry: +; CHECK-LABEL: uaddo.inc.i64 +; CHECK-NOT: incq %rdi + %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 1) + %val = extractvalue {i64, i1} %t, 0 + %obit = extractvalue {i64, i1} %t, 1 + store i64 %val, i64* %res + ret i1 %obit +} + ; SSUBO define zeroext i1 @ssubo.i32(i32 %v1, i32 %v2, i32* %res) { entry: @@ -758,6 +803,8 @@ declare {i8, i1} @llvm.sadd.with.overflow.i8 (i8, i8 ) nounwind readnone declare {i16, i1} @llvm.sadd.with.overflow.i16(i16, i16) nounwind readnone declare {i32, i1} @llvm.sadd.with.overflow.i32(i32, i32) nounwind readnone declare {i64, i1} @llvm.sadd.with.overflow.i64(i64, i64) nounwind readnone +declare {i8, i1} @llvm.uadd.with.overflow.i8 (i8, i8 ) nounwind readnone +declare {i16, i1} @llvm.uadd.with.overflow.i16(i16, i16) nounwind readnone declare {i32, i1} @llvm.uadd.with.overflow.i32(i32, i32) nounwind readnone declare {i64, i1} @llvm.uadd.with.overflow.i64(i64, i64) nounwind readnone declare {i32, i1} @llvm.ssub.with.overflow.i32(i32, i32) nounwind readnone -- 2.34.1