This is incorrect: case Instruction::FCmp: switch (CE->getPredicate()) { case FCmpInst::FCMP_ORD: case FCmpInst::FCMP_UEQ: case FCmpInst::FCMP_OEQ: Out << " == "; break; case FCmpInst::FCMP_UNO: case FCmpInst::FCMP_UNE: case FCmpInst::FCMP_ONE: Out << " != "; break; case FCmpInst::FCMP_OLT: case FCmpInst::FCMP_ULT: Out << " < "; break; case FCmpInst::FCMP_OLE: case FCmpInst::FCMP_ULE: Out << " <= "; break; case FCmpInst::FCMP_OGT: case FCmpInst::FCMP_UGT: Out << " > "; break; case FCmpInst::FCMP_OGE: case FCmpInst::FCMP_UGE: Out << " >= "; break; default: assert(0 && "Illegal FCmp predicate"); } -Chris
This should be simple (but ugly) to implement. For example: x ord y -> "x == x && y == y" x uno y -> "x != x || y != y" x ueq y -> "x == y || x != x || y != y" etc. This should probably be handled by having the CBE emit static inline functions for each operation at the top of the file. -Chris
Mine.
Fixed with this patch: http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20070108/042222.html
Cleaned up the helper functions per Chris' suggestions: > + // Emit some helper functions for dealing with FCMP instruction's > + // predicates > + Out << "static inline int llvm_fcmp_ord(double X, double Y) { "; > + Out << "return X == X && Y == Y; }\n"; > + Out << "static inline int llvm_fcmp_uno(double X, double Y) { "; > + Out << "return X != X || Y != Y; }\n"; > + Out << "static inline int llvm_fcmp_ueq(double X, double Y) { "; > + Out << "return X == Y || X != X || Y != Y; }\n"; These would be more obvious if written as: return X == Y || llvm_fcmp_uno(X, Y) > + Out << "static inline int llvm_fcmp_ult(double X, double Y) { "; > + Out << "return X < Y || X != X || Y != Y; }\n"; > + Out << "static inline int llvm_fcmp_ugt(double X, double Y) { "; > + Out << "return X > Y || X != X || Y != Y; }\n"; > + Out << "static inline int llvm_fcmp_ule(double X, double Y) { "; > + Out << "return X <= Y || X != X || Y != Y; }\n"; > + Out << "static inline int llvm_fcmp_uge(double X, double Y) { "; > + Out << "return X >= Y || X != X || Y != Y; }\n"; > + Out << "static inline int llvm_fcmp_une(double X, double Y) { "; > + Out << "return X != Y || X != X || Y != Y; }\n"; > + Out << "static inline int llvm_fcmp_oeq(double X, double Y) { "; > + Out << "return X == Y && X == X && Y == Y; }\n"; > + Out << "static inline int llvm_fcmp_olt(double X, double Y) { "; > + Out << "return X < Y && X == X && Y == Y; }\n"; > + Out << "static inline int llvm_fcmp_ogt(double X, double Y) { "; > + Out << "return X > Y && X == X && Y == Y; }\n"; > + Out << "static inline int llvm_fcmp_ole(double X, double Y) { "; > + Out << "return X <= Y && X == X && Y == Y; }\n"; > + Out << "static inline int llvm_fcmp_oge(double X, double Y) { "; > + Out << "return X >= Y && X == X && Y == Y; }\n"; You can drop the 2nd and 3rd term of each of thse. > + Out << "static inline int llvm_fcmp_one(double X, double Y) { "; > + Out << "return X != Y && X == X && Y == Y; }\n"; This one is needed though. With this patch: http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20070108/042227.html