This patch causes us to compile functions like:
p1 (f2, l)
float f2; short l; {
printf("%d\n", l);
}
into:
define i32 %p1(double %f2, i32 %l) {
instead of:
define i32 %p1(float %f2, i16 %l) {
due to K&R promotion rules. This fixes a miscompilation of
SingleSource/UnitTests/2007-01-04-KNR-Args.c on PowerPC at -O0.
-Chris
Index: llvm-convert.cpp
===================================================================
--- llvm-convert.cpp (revision 122009)
+++ llvm-convert.cpp (working copy)
@@ -211,12 +211,15 @@ namespace {
if (ArgVal->getType() != LLVMTy) {
// If this is just a mismatch between integer types, this could be due
// to K&R prototypes, where the forward proto defines the arg as int
and
- // the actual impls is a short or char.
- assert(ArgVal->getType()->isIntegral() && LLVMTy->isIntegral() &&
+ // the actual impls is a short or char. Likewise for double -> float.
+ assert(ArgVal->getType()->isIntegral() == LLVMTy->isIntegral() &&
+ (ArgVal->getType() == Type::Int32Ty ||
+ ArgVal->getType() == Type::DoubleTy) &&
"Lowerings don't match?");
- bool isSigned = type == 0 ? true : !TYPE_UNSIGNED(type);
- ArgVal = CastInst::createIntegerCast(ArgVal, LLVMTy, isSigned,
- NameStack.back(), CurBB);
+ if (ArgVal->getType() == Type::Int32Ty)
+ ArgVal = new TruncInst(ArgVal, LLVMTy, NameStack.back(), CurBB);
+ else
+ ArgVal = new FPTruncInst(ArgVal, LLVMTy, NameStack.back(), CurBB);
}
assert(!LocStack.empty());
Value *Loc = LocStack.back();
Index: llvm-types.cpp
===================================================================
--- llvm-types.cpp (revision 122009)
+++ llvm-types.cpp (working copy)
@@ -474,10 +474,11 @@ namespace {
const Type *&RetTy;
std::vector<const Type*> &ArgTypes;
unsigned &CallingConv;
+ bool KNRPromotion;
public:
FunctionTypeConversion(const Type *&retty, std::vector<const Type*> &AT,
- unsigned &CC)
- : RetTy(retty), ArgTypes(AT), CallingConv(CC) {
+ unsigned &CC, bool KNR)
+ : RetTy(retty), ArgTypes(AT), CallingConv(CC), KNRPromotion(KNR) {
CallingConv = CallingConv::C;
}
@@ -512,6 +513,16 @@ namespace {
}
void HandleScalarArgument(const llvm::Type *LLVMTy, tree type) {
+ if (KNRPromotion) {
+ if (LLVMTy == Type::FloatTy) {
+ ArgTypes.push_back(Type::DoubleTy);
+ return;
+ } else if (LLVMTy == Type::Int16Ty || LLVMTy == Type::Int8Ty ||
+ LLVMTy == Type::BoolTy) {
+ ArgTypes.push_back(Type::Int32Ty);
+ return;
+ }
+ }
ArgTypes.push_back(LLVMTy);
}
};
@@ -528,7 +539,7 @@ ConvertArgListToFnType(tree ReturnType,
std::vector<const Type*> ArgTys;
const Type *RetTy;
- FunctionTypeConversion Client(RetTy, ArgTys, CallingConv);
+ FunctionTypeConversion Client(RetTy, ArgTys, CallingConv, true /*K&R*/);
TheLLVMABI<FunctionTypeConversion> ABIConverter(Client);
ABIConverter.HandleReturnType(ReturnType);
@@ -542,7 +553,7 @@ const FunctionType *TypeConverter::Conve
const Type *RetTy = 0;
std::vector<const Type*> ArgTypes;
bool isVarArg = false;
- FunctionTypeConversion Client(RetTy, ArgTypes, CallingConv);
+ FunctionTypeConversion Client(RetTy, ArgTypes, CallingConv, true /*not
K&R*/);
TheLLVMABI<FunctionTypeConversion> ABIConverter(Client);
ABIConverter.HandleReturnType(TREE_TYPE(type));
_______________________________________________
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits