Instead of blindly looking past constantexpr casts, actually constant
authorChris Lattner <sabre@nondot.org>
Sat, 29 Jul 2006 01:57:19 +0000 (01:57 +0000)
committerChris Lattner <sabre@nondot.org>
Sat, 29 Jul 2006 01:57:19 +0000 (01:57 +0000)
fold them.  This correctly truncates constants that are too large for the
destination slot and makes the code easier to understand.  This fixes PR853
and Regression/CodeGen/X86/2006-07-28-AsmPrint-Long-As-Pointer.ll

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

lib/CodeGen/AsmPrinter.cpp

index 205c68751f6f0072f1920881dd139b0d505b5d1d..ca9b50bb81229ebe917bcb245d602ac206dbded9 100644 (file)
@@ -385,23 +385,29 @@ void AsmPrinter::EmitConstantValueOnly(const Constant *CV) {
       break;
     }
     case Instruction::Cast: {
-      // Support only non-converting or widening casts for now, that is, ones
-      // that do not involve a change in value.  This assertion is really gross,
-      // and may not even be a complete check.
+      // Support only foldable casts to/from pointers that can be eliminated by
+      // changing the pointer to the appropriately sized integer type.
       Constant *Op = CE->getOperand(0);
       const Type *OpTy = Op->getType(), *Ty = CE->getType();
 
-      // Remember, kids, pointers can be losslessly converted back and forth
-      // into 32-bit or wider integers, regardless of signedness. :-P
-      assert(((isa<PointerType>(OpTy)
-               && (Ty == Type::LongTy || Ty == Type::ULongTy
-                   || Ty == Type::IntTy || Ty == Type::UIntTy))
-              || (isa<PointerType>(Ty)
-                  && (OpTy == Type::LongTy || OpTy == Type::ULongTy
-                      || OpTy == Type::IntTy || OpTy == Type::UIntTy))
-              || (((TD->getTypeSize(Ty) >= TD->getTypeSize(OpTy))
-                   && OpTy->isLosslesslyConvertibleTo(Ty))))
-             && "FIXME: Don't yet support this kind of constant cast expr");
+      // Handle casts to pointers by changing them into casts to the appropriate
+      // integer type.  This promotes constant folding and simplifies this code.
+      if (isa<PointerType>(Ty)) {
+        const Type *IntPtrTy = TD->getIntPtrType();
+        Op = ConstantExpr::getCast(Op, IntPtrTy);
+        return EmitConstantValueOnly(Op);
+      }
+      
+      // We know the dest type is not a pointer.  Is the src value a pointer or
+      // integral?
+      if (isa<PointerType>(OpTy) || OpTy->isIntegral()) {
+        // We can emit the pointer value into this slot if the slot is an
+        // integer slot greater or equal to the size of the pointer.
+        if (Ty->isIntegral() && TD->getTypeSize(Ty) >= TD->getTypeSize(OpTy))
+          return EmitConstantValueOnly(Op);
+      }
+      
+      assert(0 && "FIXME: Don't yet support this kind of constant cast expr");
       EmitConstantValueOnly(Op);
       break;
     }