LLVM Bugzilla is read-only and represents the historical archive of all LLVM issues filled before November 26, 2021. Use github to submit LLVM bugs

Bug 1090 - CBE doesn't support exotic fcmp variants
Summary: CBE doesn't support exotic fcmp variants
Status: RESOLVED FIXED
Alias: None
Product: libraries
Classification: Unclassified
Component: Backend: C (show other bugs)
Version: trunk
Hardware: All All
: P normal
Assignee: Reid Spencer
URL:
Keywords: miscompilation
Depends on:
Blocks:
 
Reported: 2007-01-07 01:48 PST by Chris Lattner
Modified: 2010-02-22 12:50 PST (History)
1 user (show)

See Also:
Fixed By Commit(s):


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Chris Lattner 2007-01-07 01:48:55 PST
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
Comment 1 Chris Lattner 2007-01-07 01:51:03 PST
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
Comment 2 Reid Spencer 2007-01-07 15:27:20 PST
Mine.
Comment 3 Reid Spencer 2007-01-08 01:00:53 PST
Fixed with this patch:
http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20070108/042222.html
Comment 4 Reid Spencer 2007-01-08 02:02:18 PST
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