From 2476e5d3458ea3543f233159fcf4f2fea47426e9 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Wed, 10 Dec 2008 22:36:00 +0000 Subject: [PATCH] If ADD, SUB, or MUL have an overflow bit that's used, don't do transformation on them. The DAG combiner expects that nodes that are transformed have one value result. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@60857 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 15 +++++++++ test/CodeGen/X86/add-with-overflow.ll | 40 +++++++++++++++++++++--- 2 files changed, 51 insertions(+), 4 deletions(-) diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 9cc8061f183..7e78923f6d9 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -966,6 +966,11 @@ SDValue DAGCombiner::visitADD(SDNode *N) { SDValue FoldedVOp = SimplifyVBinOp(N); if (FoldedVOp.getNode()) return FoldedVOp; } + + if (N->getNumValues() != 1) + // FIXME: DAG combiner cannot handle multiple return values on arithmetic + // operators. + return SDValue(); // fold (add x, undef) -> undef if (N0.getOpcode() == ISD::UNDEF) @@ -1161,6 +1166,11 @@ SDValue DAGCombiner::visitSUB(SDNode *N) { SDValue FoldedVOp = SimplifyVBinOp(N); if (FoldedVOp.getNode()) return FoldedVOp; } + + if (N->getNumValues() != 1) + // FIXME: DAG combiner cannot handle multiple return values on arithmetic + // operators. + return SDValue(); // fold (sub x, x) -> 0 if (N0 == N1) @@ -1220,6 +1230,11 @@ SDValue DAGCombiner::visitMUL(SDNode *N) { if (FoldedVOp.getNode()) return FoldedVOp; } + if (N->getNumValues() != 1) + // FIXME: DAG combiner cannot handle multiple return values on arithmetic + // operators. + return SDValue(); + // fold (mul x, undef) -> 0 if (N0.getOpcode() == ISD::UNDEF || N1.getOpcode() == ISD::UNDEF) return DAG.getConstant(0, VT); diff --git a/test/CodeGen/X86/add-with-overflow.ll b/test/CodeGen/X86/add-with-overflow.ll index baf577168c1..4b9aa98c843 100644 --- a/test/CodeGen/X86/add-with-overflow.ll +++ b/test/CodeGen/X86/add-with-overflow.ll @@ -1,7 +1,7 @@ -; RUN: llvm-as < %s | llc -march=x86 | grep {jo} | count 1 -; RUN: llvm-as < %s | llc -march=x86 | grep {jc} | count 1 -; RUN: llvm-as < %s | llc -march=x86 -fast | grep {jo} | count 1 -; RUN: llvm-as < %s | llc -march=x86 -fast | grep {jc} | count 1 +; RUN: llvm-as < %s | llc -march=x86 | grep {jo} | count 2 +; RUN: llvm-as < %s | llc -march=x86 | grep {jc} | count 2 +; RUN: llvm-as < %s | llc -march=x86 -fast | grep {jo} | count 2 +; RUN: llvm-as < %s | llc -march=x86 -fast | grep {jc} | count 2 @ok = internal constant [4 x i8] c"%d\0A\00" @no = internal constant [4 x i8] c"no\0A\00" @@ -38,6 +38,38 @@ carry: ret i1 false } +define i1 @func3() nounwind { +entry: + %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 0, i32 0) + %sum = extractvalue {i32, i1} %t, 0 + %obit = extractvalue {i32, i1} %t, 1 + br i1 %obit, label %carry, label %normal + +normal: + %t1 = tail call i32 (i8*, ...)* @printf( i8* getelementptr ([4 x i8]* @ok, i32 0, i32 0), i32 %sum ) nounwind + ret i1 true + +carry: + %t2 = tail call i32 (i8*, ...)* @printf( i8* getelementptr ([4 x i8]* @no, i32 0, i32 0) ) nounwind + ret i1 false +} + +define i1 @func4() nounwind { +entry: + %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 0, i32 0) + %sum = extractvalue {i32, i1} %t, 0 + %obit = extractvalue {i32, i1} %t, 1 + br i1 %obit, label %carry, label %normal + +normal: + %t1 = tail call i32 (i8*, ...)* @printf( i8* getelementptr ([4 x i8]* @ok, i32 0, i32 0), i32 %sum ) nounwind + ret i1 true + +carry: + %t2 = tail call i32 (i8*, ...)* @printf( i8* getelementptr ([4 x i8]* @no, i32 0, i32 0) ) nounwind + ret i1 false +} + declare i32 @printf(i8*, ...) nounwind declare {i32, i1} @llvm.sadd.with.overflow.i32(i32, i32) declare {i32, i1} @llvm.uadd.with.overflow.i32(i32, i32)