Implement == and != correctly. Before they would incorrectly return !=
authorChris Lattner <sabre@nondot.org>
Mon, 17 Nov 2003 20:19:35 +0000 (20:19 +0000)
committerChris Lattner <sabre@nondot.org>
Mon, 17 Nov 2003 20:19:35 +0000 (20:19 +0000)
for some constant exprs when they could really be the same value

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@10058 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/ConstantHandling.h
lib/VMCore/ConstantFold.cpp
lib/VMCore/ConstantFold.h
lib/VMCore/ConstantFolding.h

index d733ac8096252cda8b9f4e280462b5193f0d2802..27eed8a7bec9f1f0a9148bc80d342a8dec1df5c4 100644 (file)
@@ -47,19 +47,6 @@ namespace llvm {
 
 class PointerType;
 
-//===----------------------------------------------------------------------===//
-//  Implement == and != directly...
-//===----------------------------------------------------------------------===//
-
-inline ConstantBool *operator==(const Constant &V1, const Constant &V2) {
-  assert(V1.getType() == V2.getType() && "Constant types must be identical!");
-  return ConstantBool::get(&V1 == &V2);
-}
-
-inline ConstantBool *operator!=(const Constant &V1, const Constant &V2) {
-  return ConstantBool::get(&V1 != &V2);
-}
-
 //===----------------------------------------------------------------------===//
 //  Implement all other operators indirectly through TypeRules system
 //===----------------------------------------------------------------------===//
@@ -81,6 +68,8 @@ struct ConstRules {
 
   virtual ConstantBool *lessthan(const Constant *V1, 
                                  const Constant *V2) const = 0;
+  virtual ConstantBool *equalto(const Constant *V1, 
+                                const Constant *V2) const = 0;
 
   // Casting operators.  ick
   virtual ConstantBool *castToBool  (const Constant *V) const = 0;
@@ -195,11 +184,21 @@ inline ConstantBool *operator<(const Constant &V1,
   return ConstRules::get(V1, V2).lessthan(&V1, &V2);
 }
 
+inline ConstantBool *operator==(const Constant &V1, const Constant &V2) {
+  assert(V1.getType() == V2.getType() && "Constant types must be identical!");
+  return ConstRules::get(V1, V2).equalto(&V1, &V2);
+}
 
 //===----------------------------------------------------------------------===//
 //  Implement 'derived' operators based on what we already have...
 //===----------------------------------------------------------------------===//
 
+inline ConstantBool *operator!=(const Constant &V1, const Constant &V2) {
+  if (ConstantBool *V = (V1 == V2))
+    return V->inverted();                // !(V1 == V2)
+  return 0;
+}
+
 inline ConstantBool *operator>(const Constant &V1, 
                                const Constant &V2) {
   return V2 < V1;
index 5e7bd0296590e97d8ba7d915fabf1524c72760e0..d86ef11ecf500445cf986261d7f75ce2c1eb958e 100644 (file)
@@ -256,6 +256,10 @@ class TemplateRules : public ConstRules {
                                  const Constant *V2) const { 
     return SubClassName::LessThan((const ArgType *)V1, (const ArgType *)V2);
   }
+  virtual ConstantBool *equalto(const Constant *V1, 
+                                const Constant *V2) const { 
+    return SubClassName::EqualTo((const ArgType *)V1, (const ArgType *)V2);
+  }
 
   // Casting operators.  ick
   virtual ConstantBool *castToBool(const Constant *V) const {
@@ -313,6 +317,9 @@ class TemplateRules : public ConstRules {
   static ConstantBool *LessThan(const ArgType *V1, const ArgType *V2) {
     return 0;
   }
+  static ConstantBool *EqualTo(const ArgType *V1, const ArgType *V2) {
+    return 0;
+  }
 
   // Casting operators.  ick
   static ConstantBool *CastToBool  (const Constant *V) { return 0; }
@@ -339,6 +346,10 @@ class TemplateRules : public ConstRules {
 // EmptyRules provides a concrete base class of ConstRules that does nothing
 //
 struct EmptyRules : public TemplateRules<Constant, EmptyRules> {
+  static ConstantBool *EqualTo(const Constant *V1, const Constant *V2) {
+    if (V1 == V2) return ConstantBool::True;
+    return 0;
+  }
 };
 
 
@@ -355,6 +366,10 @@ struct BoolRules : public TemplateRules<ConstantBool, BoolRules> {
     return ConstantBool::get(V1->getValue() < V2->getValue());
   }
 
+  static ConstantBool *EqualTo(const Constant *V1, const Constant *V2) {
+    return ConstantBool::get(V1 == V2);
+  }
+
   static Constant *And(const ConstantBool *V1, const ConstantBool *V2) {
     return ConstantBool::get(V1->getValue() & V2->getValue());
   }
@@ -397,6 +412,9 @@ struct BoolRules : public TemplateRules<ConstantBool, BoolRules> {
 //
 struct NullPointerRules : public TemplateRules<ConstantPointerNull,
                                                NullPointerRules> {
+  static ConstantBool *EqualTo(const Constant *V1, const Constant *V2) {
+    return ConstantBool::True;  // Null pointers are always equal
+  }
   static ConstantBool *CastToBool  (const Constant *V) {
     return ConstantBool::False;
   }
@@ -475,6 +493,12 @@ struct DirectRules : public TemplateRules<ConstantClass, SuperClass> {
     return ConstantBool::get(R);
   } 
 
+  static ConstantBool *EqualTo(const ConstantClass *V1,
+                               const ConstantClass *V2) {
+    bool R = (BuiltinType)V1->getValue() == (BuiltinType)V2->getValue();
+    return ConstantBool::get(R);
+  }
+
   static Constant *CastToPointer(const ConstantClass *V,
                                  const PointerType *PTy) {
     if (V->isNullValue())    // Is it a FP or Integral null value?
index d733ac8096252cda8b9f4e280462b5193f0d2802..27eed8a7bec9f1f0a9148bc80d342a8dec1df5c4 100644 (file)
@@ -47,19 +47,6 @@ namespace llvm {
 
 class PointerType;
 
-//===----------------------------------------------------------------------===//
-//  Implement == and != directly...
-//===----------------------------------------------------------------------===//
-
-inline ConstantBool *operator==(const Constant &V1, const Constant &V2) {
-  assert(V1.getType() == V2.getType() && "Constant types must be identical!");
-  return ConstantBool::get(&V1 == &V2);
-}
-
-inline ConstantBool *operator!=(const Constant &V1, const Constant &V2) {
-  return ConstantBool::get(&V1 != &V2);
-}
-
 //===----------------------------------------------------------------------===//
 //  Implement all other operators indirectly through TypeRules system
 //===----------------------------------------------------------------------===//
@@ -81,6 +68,8 @@ struct ConstRules {
 
   virtual ConstantBool *lessthan(const Constant *V1, 
                                  const Constant *V2) const = 0;
+  virtual ConstantBool *equalto(const Constant *V1, 
+                                const Constant *V2) const = 0;
 
   // Casting operators.  ick
   virtual ConstantBool *castToBool  (const Constant *V) const = 0;
@@ -195,11 +184,21 @@ inline ConstantBool *operator<(const Constant &V1,
   return ConstRules::get(V1, V2).lessthan(&V1, &V2);
 }
 
+inline ConstantBool *operator==(const Constant &V1, const Constant &V2) {
+  assert(V1.getType() == V2.getType() && "Constant types must be identical!");
+  return ConstRules::get(V1, V2).equalto(&V1, &V2);
+}
 
 //===----------------------------------------------------------------------===//
 //  Implement 'derived' operators based on what we already have...
 //===----------------------------------------------------------------------===//
 
+inline ConstantBool *operator!=(const Constant &V1, const Constant &V2) {
+  if (ConstantBool *V = (V1 == V2))
+    return V->inverted();                // !(V1 == V2)
+  return 0;
+}
+
 inline ConstantBool *operator>(const Constant &V1, 
                                const Constant &V2) {
   return V2 < V1;
index d733ac8096252cda8b9f4e280462b5193f0d2802..27eed8a7bec9f1f0a9148bc80d342a8dec1df5c4 100644 (file)
@@ -47,19 +47,6 @@ namespace llvm {
 
 class PointerType;
 
-//===----------------------------------------------------------------------===//
-//  Implement == and != directly...
-//===----------------------------------------------------------------------===//
-
-inline ConstantBool *operator==(const Constant &V1, const Constant &V2) {
-  assert(V1.getType() == V2.getType() && "Constant types must be identical!");
-  return ConstantBool::get(&V1 == &V2);
-}
-
-inline ConstantBool *operator!=(const Constant &V1, const Constant &V2) {
-  return ConstantBool::get(&V1 != &V2);
-}
-
 //===----------------------------------------------------------------------===//
 //  Implement all other operators indirectly through TypeRules system
 //===----------------------------------------------------------------------===//
@@ -81,6 +68,8 @@ struct ConstRules {
 
   virtual ConstantBool *lessthan(const Constant *V1, 
                                  const Constant *V2) const = 0;
+  virtual ConstantBool *equalto(const Constant *V1, 
+                                const Constant *V2) const = 0;
 
   // Casting operators.  ick
   virtual ConstantBool *castToBool  (const Constant *V) const = 0;
@@ -195,11 +184,21 @@ inline ConstantBool *operator<(const Constant &V1,
   return ConstRules::get(V1, V2).lessthan(&V1, &V2);
 }
 
+inline ConstantBool *operator==(const Constant &V1, const Constant &V2) {
+  assert(V1.getType() == V2.getType() && "Constant types must be identical!");
+  return ConstRules::get(V1, V2).equalto(&V1, &V2);
+}
 
 //===----------------------------------------------------------------------===//
 //  Implement 'derived' operators based on what we already have...
 //===----------------------------------------------------------------------===//
 
+inline ConstantBool *operator!=(const Constant &V1, const Constant &V2) {
+  if (ConstantBool *V = (V1 == V2))
+    return V->inverted();                // !(V1 == V2)
+  return 0;
+}
+
 inline ConstantBool *operator>(const Constant &V1, 
                                const Constant &V2) {
   return V2 < V1;