[llvm-commits] [llvm] r51559 - in /llvm/trunk: include/llvm/Analysis/ConstantFolding.h lib/Analysis/ConstantFolding.cpp lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/2008-05-18-FoldIntToPtr.ll

Nick Lewycky nicholas at mxc.ca
Sun May 25 13:56:16 PDT 2008


Author: nicholas
Date: Sun May 25 15:56:15 2008
New Revision: 51559

URL: http://llvm.org/viewvc/llvm-project?rev=51559&view=rev
Log:
"ret (constexpr)" can't be folded into a Constant. Add a method to
Analysis/ConstantFolding to fold ConstantExpr's, then make instcombine use it
to try to use targetdata to fold constant expressions on void instructions.

Also extend the icmp(inttoptr, inttoptr) folding to handle the case where
int size != ptr size.

Added:
    llvm/trunk/test/Transforms/InstCombine/2008-05-18-FoldIntToPtr.ll
Modified:
    llvm/trunk/include/llvm/Analysis/ConstantFolding.h
    llvm/trunk/lib/Analysis/ConstantFolding.cpp
    llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp

Modified: llvm/trunk/include/llvm/Analysis/ConstantFolding.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ConstantFolding.h?rev=51559&r1=51558&r2=51559&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Analysis/ConstantFolding.h (original)
+++ llvm/trunk/include/llvm/Analysis/ConstantFolding.h Sun May 25 15:56:15 2008
@@ -30,6 +30,12 @@
 ///
 Constant *ConstantFoldInstruction(Instruction *I, const TargetData *TD = 0);
 
+/// ConstantFoldConstantExpression - Attempt to fold the constant expression
+/// using the specified TargetData.  If successful, the constant result is
+/// result is returned, if not, null is returned.
+Constant *ConstantFoldConstantExpression(ConstantExpr *CE,
+                                         const TargetData *TD);
+
 /// ConstantFoldInstOperands - Attempt to constant fold an instruction with the
 /// specified operands.  If successful, the constant result is returned, if not,
 /// null is returned.  Note that this function can fail when attempting to 

Modified: llvm/trunk/lib/Analysis/ConstantFolding.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ConstantFolding.cpp?rev=51559&r1=51558&r2=51559&view=diff

==============================================================================
--- llvm/trunk/lib/Analysis/ConstantFolding.cpp (original)
+++ llvm/trunk/lib/Analysis/ConstantFolding.cpp Sun May 25 15:56:15 2008
@@ -312,6 +312,25 @@
                                     &Ops[0], Ops.size(), TD);
 }
 
+/// ConstantFoldConstantExpression - Attempt to fold the constant expression
+/// using the specified TargetData.  If successful, the constant result is
+/// result is returned, if not, null is returned.
+Constant *llvm::ConstantFoldConstantExpression(ConstantExpr *CE,
+                                               const TargetData *TD) {
+  assert(TD && "ConstantFoldConstantExpression requires a valid TargetData.");
+
+  SmallVector<Constant*, 8> Ops;
+  for (User::op_iterator i = CE->op_begin(), e = CE->op_end(); i != e; ++i)
+    Ops.push_back(cast<Constant>(*i));
+
+  if (CE->isCompare())
+    return ConstantFoldCompareInstOperands(CE->getPredicate(),
+                                           &Ops[0], Ops.size(), TD);
+  else 
+    return ConstantFoldInstOperands(CE->getOpcode(), CE->getType(),
+                                    &Ops[0], Ops.size(), TD);
+}
+
 /// ConstantFoldInstOperands - Attempt to constant fold an instruction with the
 /// specified opcode and operands.  If successful, the constant result is
 /// returned, if not, null is returned.  Note that this function can fail when
@@ -398,7 +417,7 @@
                                                 const TargetData *TD) {
   // fold: icmp (inttoptr x), null         -> icmp x, 0
   // fold: icmp (ptrtoint x), 0            -> icmp x, null
-  // fold: icmp (inttoptr x), (inttoptr y) -> icmp x, y
+  // fold: icmp (inttoptr x), (inttoptr y) -> icmp trunc/zext x, trunc/zext y
   // fold: icmp (ptrtoint x), (ptrtoint y) -> icmp x, y
   //
   // ConstantExpr::getCompare cannot do this, because it doesn't have TD
@@ -426,21 +445,31 @@
       }
     }
     
-    if (TD && isa<ConstantExpr>(Ops[1]) &&
-        cast<ConstantExpr>(Ops[1])->getOpcode() == CE0->getOpcode()) {
-      const Type *IntPtrTy = TD->getIntPtrType();
-      // Only do this transformation if the int is intptrty in size, otherwise
-      // there is a truncation or extension that we aren't modeling.
-      if ((CE0->getOpcode() == Instruction::IntToPtr &&
-           CE0->getOperand(0)->getType() == IntPtrTy &&
-           Ops[1]->getOperand(0)->getType() == IntPtrTy) ||
-          (CE0->getOpcode() == Instruction::PtrToInt &&
-           CE0->getType() == IntPtrTy &&
-           CE0->getOperand(0)->getType() == Ops[1]->getOperand(0)->getType())) {
-        Constant *NewOps[] = { 
-          CE0->getOperand(0), cast<ConstantExpr>(Ops[1])->getOperand(0) 
-        };
-        return ConstantFoldCompareInstOperands(Predicate, NewOps, 2, TD);
+    if (ConstantExpr *CE1 = dyn_cast<ConstantExpr>(Ops[1])) {
+      if (TD && CE0->getOpcode() == CE1->getOpcode()) {
+        const Type *IntPtrTy = TD->getIntPtrType();
+
+        if (CE0->getOpcode() == Instruction::IntToPtr) {
+          // Convert the integer value to the right size to ensure we get the
+          // proper extension or truncation.
+          Constant *C0 = ConstantExpr::getIntegerCast(CE0->getOperand(0),
+                                                      IntPtrTy, false);
+          Constant *C1 = ConstantExpr::getIntegerCast(CE1->getOperand(0),
+                                                      IntPtrTy, false);
+          Constant *NewOps[] = { C0, C1 };
+          return ConstantFoldCompareInstOperands(Predicate, NewOps, 2, TD);
+        }
+
+        // Only do this transformation if the int is intptrty in size, otherwise
+        // there is a truncation or extension that we aren't modeling.
+        if ((CE0->getOpcode() == Instruction::PtrToInt &&
+             CE0->getType() == IntPtrTy &&
+             CE0->getOperand(0)->getType() == CE1->getOperand(0)->getType())) {
+          Constant *NewOps[] = { 
+            CE0->getOperand(0), CE1->getOperand(0) 
+          };
+          return ConstantFoldCompareInstOperands(Predicate, NewOps, 2, TD);
+        }
       }
     }
   }

Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=51559&r1=51558&r2=51559&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Sun May 25 15:56:15 2008
@@ -11887,6 +11887,16 @@
       continue;
     }
 
+    if (TD && I->getType()->getTypeID() == Type::VoidTyID) {
+      // See if we can constant fold its operands.
+      for (User::op_iterator i = I->op_begin(), e = I->op_end(); i != e; ++i) {
+        if (ConstantExpr *CE = dyn_cast<ConstantExpr>(i)) {
+          if (Constant *NewC = ConstantFoldConstantExpression(CE, TD))
+            i->set(NewC);
+        }
+      }
+    }
+
     // See if we can trivially sink this instruction to a successor basic block.
     // FIXME: Remove GetResultInst test when first class support for aggregates
     // is implemented.

Added: llvm/trunk/test/Transforms/InstCombine/2008-05-18-FoldIntToPtr.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/2008-05-18-FoldIntToPtr.ll?rev=51559&view=auto

==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/2008-05-18-FoldIntToPtr.ll (added)
+++ llvm/trunk/test/Transforms/InstCombine/2008-05-18-FoldIntToPtr.ll Sun May 25 15:56:15 2008
@@ -0,0 +1,13 @@
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep {ret i1 false} | count 2
+; PR2329
+
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32"
+target triple = "i386-pc-linux-gnu"
+
+define i1 @f1() {
+  ret i1 icmp eq (i8* inttoptr (i32 1 to i8*), i8* inttoptr (i32 2 to i8*))
+}
+
+define i1 @f2() {
+  ret i1 icmp eq (i8* inttoptr (i16 1 to i8*), i8* inttoptr (i16 2 to i8*))
+}





More information about the llvm-commits mailing list