From: Bill Wendling Date: Wed, 10 Dec 2008 22:36:00 +0000 (+0000) Subject: If ADD, SUB, or MUL have an overflow bit that's used, don't do transformation on X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=2476e5d3458ea3543f233159fcf4f2fea47426e9;p=oota-llvm.git 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 --- 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)