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 &ArgTypes; unsigned &CallingConv; + bool KNRPromotion; public: FunctionTypeConversion(const Type *&retty, std::vector &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 ArgTys; const Type *RetTy; - FunctionTypeConversion Client(RetTy, ArgTys, CallingConv); + FunctionTypeConversion Client(RetTy, ArgTys, CallingConv, true /*K&R*/); TheLLVMABI ABIConverter(Client); ABIConverter.HandleReturnType(ReturnType); @@ -542,7 +553,7 @@ const FunctionType *TypeConverter::Conve const Type *RetTy = 0; std::vector ArgTypes; bool isVarArg = false; - FunctionTypeConversion Client(RetTy, ArgTypes, CallingConv); + FunctionTypeConversion Client(RetTy, ArgTypes, CallingConv, true /*not K&R*/); TheLLVMABI ABIConverter(Client); ABIConverter.HandleReturnType(TREE_TYPE(type));