short circuit && and || when possible.  This substantially reduces
the size of the -O0 output on some cases.  For example, on expr.c from
176.gcc, it shrinks the .ll file from 43164 to 42835 lines, and removed
references to two external symbols.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@59034 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp
index 7d3157b..4a17938 100644
--- a/lib/CodeGen/CGExprScalar.cpp
+++ b/lib/CodeGen/CGExprScalar.cpp
@@ -1028,6 +1028,20 @@
 Value *ScalarExprEmitter::VisitBinLAnd(const BinaryOperator *E) {
   Value *LHSCond = CGF.EvaluateExprAsBool(E->getLHS());
   
+  if (llvm::ConstantInt *LHSCst = dyn_cast<llvm::ConstantInt>(LHSCond)) {
+    // If we have 0 && RHS, see if we can elide RHS, if so, just return LHSCond.
+    if (LHSCst->getZExtValue() == 0) {
+      if (!CGF.ContainsLabel(E->getRHS()))
+        // Elide RHS, return 0
+        return llvm::Constant::getNullValue(CGF.LLVMIntTy);
+    } else {
+      // If we have 1 && X, just emit X without inserting the control flow.
+      Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS());
+      // ZExt result to int.
+      return Builder.CreateZExt(RHSCond, CGF.LLVMIntTy, "land.ext");
+    }
+  }
+  
   llvm::BasicBlock *ContBlock = llvm::BasicBlock::Create("land_cont");
   llvm::BasicBlock *RHSBlock = llvm::BasicBlock::Create("land_rhs");
   
@@ -1055,6 +1069,20 @@
 Value *ScalarExprEmitter::VisitBinLOr(const BinaryOperator *E) {
   Value *LHSCond = CGF.EvaluateExprAsBool(E->getLHS());
   
+  if (llvm::ConstantInt *LHSCst = dyn_cast<llvm::ConstantInt>(LHSCond)) {
+    // If we have 1 || RHS, see if we can elide RHS, if so, just return LHSCond.
+    if (LHSCst->getZExtValue() != 0) {
+      if (!CGF.ContainsLabel(E->getRHS()))
+        // Elide RHS, return 1
+        return llvm::ConstantInt::get(CGF.LLVMIntTy, 1);
+    } else {
+      // If we have 0 || X, just emit X without inserting the control flow.
+      Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS());
+      // ZExt result to int.
+      return Builder.CreateZExt(RHSCond, CGF.LLVMIntTy, "lor.ext");
+    }
+  }
+  
   llvm::BasicBlock *ContBlock = CGF.createBasicBlock("lor_cont");
   llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("lor_rhs");