diff --git a/test/CodeGen/X86/2007-04-25-MMX-PADDQ.ll b/test/CodeGen/X86/2007-04-25-MMX-PADDQ.ll index 113d0eb8647..c39b82a1fe3 100644 --- a/test/CodeGen/X86/2007-04-25-MMX-PADDQ.ll +++ b/test/CodeGen/X86/2007-04-25-MMX-PADDQ.ll @@ -1,12 +1,16 @@ -; RUN: llc < %s -o - -march=x86 -mattr=+mmx | grep paddq | count 2 -; RUN: llc < %s -o - -march=x86 -mattr=+mmx | grep movq | count 2 +; RUN: llc < %s -o - -march=x86 -mattr=+mmx | FileCheck %s -define <1 x i64> @unsigned_add3(<1 x i64>* %a, <1 x i64>* %b, i32 %count) { +define <1 x i64> @unsigned_add3(<1 x i64>* %a, <1 x i64>* %b, i32 %count) nounwind { entry: %tmp2942 = icmp eq i32 %count, 0 ; [#uses=1] br i1 %tmp2942, label %bb31, label %bb26 bb26: ; preds = %bb26, %entry + +; CHECK: movq ({{.*}},8), %mm +; CHECK: paddq ({{.*}},8), %mm +; CHECK: paddq %mm{{[0-7]}}, %mm + %i.037.0 = phi i32 [ 0, %entry ], [ %tmp25, %bb26 ] ; [#uses=3] %sum.035.0 = phi <1 x i64> [ zeroinitializer, %entry ], [ %tmp22, %bb26 ] ; <<1 x i64>> [#uses=1] %tmp13 = getelementptr <1 x i64>* %b, i32 %i.037.0 ; <<1 x i64>*> [#uses=1] diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp index 6bb239ac69a..a29c5539fc8 100644 --- a/utils/TableGen/CodeGenDAGPatterns.cpp +++ b/utils/TableGen/CodeGenDAGPatterns.cpp @@ -1591,6 +1591,40 @@ TreePatternNode *TreePattern::ParseTreePattern(Init *TheInit, StringRef OpName){ return Result; } +/// SimplifyTree - See if we can simplify this tree to eliminate something that +/// will never match in favor of something obvious that will. This is here +/// strictly as a convenience to target authors because it allows them to write +/// more type generic things and have useless type casts fold away. +/// +/// This returns true if any change is made. +static bool SimplifyTree(TreePatternNode *&N) { + if (N->isLeaf()) + return false; + + // If we have a bitconvert with a resolved type and if the source and + // destination types are the same, then the bitconvert is useless, remove it. + if (N->getOperator()->getName() == "bitconvert" && + N->getNumChildren() > 0 && // FIXME + N->getExtType(0).isConcrete() && + N->getExtType(0) == N->getChild(0)->getExtType(0) && + N->getName().empty()) { + N = N->getChild(0); + SimplifyTree(N); + return true; + } + + // Walk all children. + bool MadeChange = false; + for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) { + TreePatternNode *Child = N->getChild(i); + MadeChange |= SimplifyTree(Child); + N->setChild(i, Child); + } + return MadeChange; +} + + + /// InferAllTypes - Infer/propagate as many types throughout the expression /// patterns as possible. Return true if all types are inferred, false /// otherwise. Throw an exception if a type contradiction is found. @@ -1602,8 +1636,10 @@ InferAllTypes(const StringMap > *InNamedTypes) { bool MadeChange = true; while (MadeChange) { MadeChange = false; - for (unsigned i = 0, e = Trees.size(); i != e; ++i) + for (unsigned i = 0, e = Trees.size(); i != e; ++i) { MadeChange |= Trees[i]->ApplyTypeConstraints(*this, false); + MadeChange |= SimplifyTree(Trees[i]); + } // If there are constraints on our named nodes, apply them. for (StringMap >::iterator