]> granicus.if.org Git - clang/commitdiff
More complete/correct implementation of the comparison operators for
authorEli Friedman <eli.friedman@gmail.com>
Thu, 29 May 2008 15:17:49 +0000 (15:17 +0000)
committerEli Friedman <eli.friedman@gmail.com>
Thu, 29 May 2008 15:17:49 +0000 (15:17 +0000)
constant expressions.

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

lib/CodeGen/CGExprConstant.cpp
test/CodeGen/constant-comparison.c [new file with mode: 0644]

index a642fd236d38eb673c7d26ab486ba49cca22e6d6..c61d71acada13d695eac73d062bfb1b7409c2d34 100644 (file)
@@ -385,20 +385,60 @@ public:
     return llvm::ConstantExpr::getAnd(LHS, RHS);
   }
 
-  llvm::Constant *VisitBinNE(const BinaryOperator *E) {
+  llvm::Constant *EmitCmp(const BinaryOperator *E,
+                          llvm::CmpInst::Predicate SignedPred,
+                          llvm::CmpInst::Predicate UnsignedPred,
+                          llvm::CmpInst::Predicate FloatPred) {
     llvm::Constant *LHS = Visit(E->getLHS());
     llvm::Constant *RHS = Visit(E->getRHS());
-
-    const llvm::Type* ResultType = ConvertType(E->getType());
-    if (!ResultType->isInteger()) {
+    llvm::Constant *Result;
+    if (LHS->getType()->isInteger() ||
+        isa<llvm::PointerType>(LHS->getType())) {
+      if (E->getLHS()->getType()->isSignedIntegerType())
+        Result = llvm::ConstantExpr::getICmp(SignedPred, LHS, RHS);
+      else
+        Result = llvm::ConstantExpr::getICmp(UnsignedPred, LHS, RHS);
+    } else if (LHS->getType()->isFloatingPoint()) {
+      Result = llvm::ConstantExpr::getFCmp(FloatPred, LHS, RHS);
+    } else {
       CGM.WarnUnsupported(E, "constant expression");
-      return llvm::Constant::getNullValue(ConvertType(E->getType()));
+      Result = llvm::ConstantInt::getFalse();
     }
-    llvm::Constant *Result =
-        llvm::ConstantExpr::getICmp(llvm::ICmpInst::ICMP_NE, LHS, RHS);
+
+    const llvm::Type* ResultType = ConvertType(E->getType());
     return llvm::ConstantExpr::getZExtOrBitCast(Result, ResultType);
   }
 
+  llvm::Constant *VisitBinNE(const BinaryOperator *E) {
+    return EmitCmp(E, llvm::CmpInst::ICMP_NE, llvm::CmpInst::ICMP_NE,
+                   llvm::CmpInst::FCMP_ONE);
+  }
+
+  llvm::Constant *VisitBinEQ(const BinaryOperator *E) {
+    return EmitCmp(E, llvm::CmpInst::ICMP_EQ, llvm::CmpInst::ICMP_EQ,
+                   llvm::CmpInst::FCMP_OEQ);
+  }
+
+  llvm::Constant *VisitBinLT(const BinaryOperator *E) {
+    return EmitCmp(E, llvm::CmpInst::ICMP_SLT, llvm::CmpInst::ICMP_ULT,
+                   llvm::CmpInst::FCMP_OLT);
+  }
+
+  llvm::Constant *VisitBinLE(const BinaryOperator *E) {
+    return EmitCmp(E, llvm::CmpInst::ICMP_SLE, llvm::CmpInst::ICMP_ULE,
+                   llvm::CmpInst::FCMP_OLE);
+  }
+
+  llvm::Constant *VisitBinGT(const BinaryOperator *E) {
+    return EmitCmp(E, llvm::CmpInst::ICMP_SGT, llvm::CmpInst::ICMP_UGT,
+                   llvm::CmpInst::FCMP_OGT);
+  }
+
+  llvm::Constant *VisitBinGE(const BinaryOperator *E) {
+    return EmitCmp(E, llvm::CmpInst::ICMP_SGE, llvm::CmpInst::ICMP_SGE,
+                   llvm::CmpInst::FCMP_OGE);
+  }
+
   llvm::Constant *VisitConditionalOperator(const ConditionalOperator *E) {
     llvm::Constant *Cond = Visit(E->getCond());
     llvm::Constant *CondVal = EmitConversionToBool(Cond, E->getType());
diff --git a/test/CodeGen/constant-comparison.c b/test/CodeGen/constant-comparison.c
new file mode 100644 (file)
index 0000000..bc48ac4
--- /dev/null
@@ -0,0 +1,12 @@
+// RUN: clang -emit-llvm %s -o - 2>&1 | not grep warning
+// RUN: clang -emit-llvm %s -o - | grep @b | count 1
+
+int a, b;
+int *c1 = 1 < 2 ? &a : &b;
+int *c2 = 3 != 3LL ? &b : &a;
+int *c3 = !(3 <= 4.0) ? &b : &a;
+int *c4 = &a - (6 * 5 > 30);
+int *c5 = &a + (6 * 5 >= 30);
+int c6 = 44 < 33;
+
+