[llvm-commits] getInferredCast proposal

Chris Lattner clattner at apple.com
Mon Dec 4 11:11:07 PST 2006


Reid,

Most of your uses of getInferredCast fall into one of these categories:

1. They can only be one type of cast.
2. They can be a [bitcast or trunc]  or [bitcast or zext] or [bitcast  
or sext].

The former should be eliminated obviously, so I want to talk about  
the later.

As a specific example, consider:

          // gep null, C is equal to C*sizeof(nullty).  If nullty is  
a known llvm
          // type, we can statically fold this.
          Constant *R = ConstantInt::get(Type::UIntTy, ElSize);
+        // We know R is unsigned, Idx0 is signed because it must be  
an index
+        // through a sequential type (gep pointer operand) which is  
always
+        // signed.
+        R = ConstantExpr::getInferredCast(R, false, Idx0->getType(),  
true);
+        R = ConstantExpr::getMul(R, Idx0); // signed multiply
+        // R is a signed integer, C is the GEP pointer so -> IntToPtr
+        return ConstantExpr::getCast(Instruction::IntToPtr, R, C- 
 >getType());

In this case, we know that the cast is either bitcast to uint/int or  
a zext to long/ulong [1].  Because you know this, you have a 3 line  
comment trying to explain what is going on, and that comment is  
confusing (it talks about the types of values, when values are about  
to be untyped).

What we really want to do is talk about the possible extension  
happening here.  As such, I think it would be much cleaner to split  
up getInferredCast into:

ConstantExpr::getZExtOrBitCast(..)
ConstantExpr::getSExtOrBitCast(..)
ConstantExpr::getTruncOrBitCast(..)

This would allow writing this code as:

          // gep null, C is equal to C*sizeof(nullty).  If nullty is  
a known llvm
          // type, we can statically fold this.
          Constant *R = ConstantInt::get(Type::UIntTy, ElSize);
+        R = ConstantExpr::getZExtOrBitCast(R, Idx0->getType());
+        R = ConstantExpr::getMul(R, Idx0); // signed multiply
+        // R is a signed integer, C is the GEP pointer so -> IntToPtr
+        return ConstantExpr::getCast(Instruction::IntToPtr, R, C- 
 >getType());

The need for the comment goes away.  Even *better*, the method can  
assert that the types make sense for this (e.g. a trunc isn't from  
smaller to larger) as opposed to the totally unconstrained  
getInferredCast.

This makes the code a) more self documenting as to what is going on  
and b) much more strict about checking itself.  What do you think?   
Would this allow us to completely eliminate getInferredCast?

-Chris

[1]. As an aside, if you relaxed the type constraints of GEP indices,  
this gets much messier.



More information about the llvm-commits mailing list