From ce3900849a3b5d43d27ad0fa4d94ff6c12afc9f0 Mon Sep 17 00:00:00 2001 From: Pete Cooper Date: Mon, 13 Feb 2012 00:10:03 +0000 Subject: Fixed bug when custom lowering DEC64m on x86. If the DEC node had more than one user, it was doing this lowering but leaving the original DEC node around and so decrementing twice. Fixes PR11964. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@150356 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/X86ISelDAGToDAG.cpp | 1 + test/CodeGen/X86/dec-eflags-lower.ll | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/lib/Target/X86/X86ISelDAGToDAG.cpp b/lib/Target/X86/X86ISelDAGToDAG.cpp index 830cb65..709be5f 100644 --- a/lib/Target/X86/X86ISelDAGToDAG.cpp +++ b/lib/Target/X86/X86ISelDAGToDAG.cpp @@ -2378,6 +2378,7 @@ SDNode *X86DAGToDAGISel::Select(SDNode *Node) { Chain->getOpcode() != ISD::LOAD || StoredVal->getOpcode() != X86ISD::DEC || StoredVal.getResNo() != 0 || + !StoredVal.getNode()->hasNUsesOfValue(1, 0) || StoredVal->getOperand(0).getNode() != Chain.getNode()) break; diff --git a/test/CodeGen/X86/dec-eflags-lower.ll b/test/CodeGen/X86/dec-eflags-lower.ll index 458160a..841a461 100644 --- a/test/CodeGen/X86/dec-eflags-lower.ll +++ b/test/CodeGen/X86/dec-eflags-lower.ll @@ -2,6 +2,7 @@ %struct.obj = type { i64 } +; CHECK: _Z7releaseP3obj define void @_Z7releaseP3obj(%struct.obj* nocapture %o) nounwind uwtable ssp { entry: ; CHECK: decq (%{{rdi|rcx}}) @@ -22,8 +23,31 @@ return: ; preds = %entry, %if.end ret void } +@c = common global i64 0, align 8 +@a = common global i32 0, align 4 +@.str = private unnamed_addr constant [5 x i8] c"%ld\0A\00", align 1 +@b = common global i32 0, align 4 + +; CHECK: test +define i32 @test() nounwind uwtable ssp { +entry: +; CHECK: decq +; CHECK-NOT: decq +%0 = load i64* @c, align 8, !tbaa !0 +%dec.i = add nsw i64 %0, -1 +store i64 %dec.i, i64* @c, align 8, !tbaa !0 +%tobool.i = icmp ne i64 %dec.i, 0 +%lor.ext.i = zext i1 %tobool.i to i32 +store i32 %lor.ext.i, i32* @a, align 4, !tbaa !3 +%call = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([5 x i8]* @.str, i64 0, i64 0), i64 %dec.i) nounwind +ret i32 0 +} + +declare i32 @printf(i8* nocapture, ...) nounwind + declare void @free(i8* nocapture) nounwind !0 = metadata !{metadata !"long", metadata !1} !1 = metadata !{metadata !"omnipotent char", metadata !2} !2 = metadata !{metadata !"Simple C/C++ TBAA", null} +!3 = metadata !{metadata !"int", metadata !1} -- cgit v1.1