All, The attached patch removes all but one isSigned() calls from llvm-convert.cpp and otherwise makes it signless. This cleans up the casting patch committed yesterday and bases signedness only on TYPE_UNSIGNED(TREE_TYPE(tree)). The one exception can't be removed until the signed and unsigned integer types are unified.
Although I've tested this extensively and it causes no regressions, it needs to be reviewed. In particular, in two places I have changed casts-to-bool into SetCondInst to prevent "trunc to bool" semantics which could break things. Some things to note: 1. EmitAsScalarType was just another name for a CastToType and had exactly one use so I just removed it and replaced its call with a CastToType call. 2. I've added several CastToXXType functions near the beginning of the file to assist with casting int<->int, fp<->fp, and any<->any. This just prevents a little opcode selection logic from being sprinkled throughout the source. 3. Most of the changes to llvm-types.cpp is just wrapping long lines. I noticed it so figured I'd fix it. 4. I added a tree typed argument to HandleScalarArgument so the signedness can be derived. This isn't always used, but its the only accurate way to get the signedness in a couple cases where it is used. If 0 is passed in, it defaults to unsigned. 5. In two places (1787 and 2516) I removed some casting. These were remnants from the SHIFT patch. Since shift no longer cares about the sign of its operands, there's no need to cast them to force a particular kind of shift. 6. The NOOPCastToType function is a misnomer. The casts it produces are often not BitCast (the only "noop" cast we have). It can do integer conversions and Ptr<->Int as well. I couldn't think of a better name for this so I just left it. 7. The rest of the changes are of two forms: (a) change a cast to use a specific cast opcode, or (b) change a cast to use an opcode derived from CastInst::getCastOpcode and the signedness information from the gcc tree available. One small step towards signlessness. Reid.
Index: gcc/llvm-abi.h =================================================================== --- gcc/llvm-abi.h (revision 230) +++ gcc/llvm-abi.h (working copy) @@ -64,7 +64,7 @@ /// HandleScalarArgument - This is the primary callback that specifies an LLVM /// argument to pass. - void HandleScalarArgument(const llvm::Type *LLVMTy) {} + void HandleScalarArgument(const llvm::Type *LLVMTy, tree argTreeType) {} /// EnterField - Called when we're about the enter the field of a struct /// or union. FieldNo is the number of the element we are entering in the @@ -191,9 +191,9 @@ const Type *Ty = ConvertType(type); if (TREE_ADDRESSABLE(type)) { // Constructible object, pass by-ref - C.HandleScalarArgument(PointerType::get(Ty)); + C.HandleScalarArgument(PointerType::get(Ty), type); } else if (Ty->isFirstClassType()) { - C.HandleScalarArgument(Ty); + C.HandleScalarArgument(Ty, type); } else if (LLVM_SHOULD_PASS_AGGREGATE_IN_INTEGER_REGS(type)) { PassInIntegerRegisters(type, Ty); } else if (TREE_CODE(type) == RECORD_TYPE) { @@ -289,10 +289,10 @@ for (unsigned i = 0, e = Elts.size(); i != e; ++i) { C.EnterField(i, STy); - C.HandleScalarArgument(Elts[i]); + C.HandleScalarArgument(Elts[i], 0); C.ExitField(); } - } + } }; /// TheLLVMABI - This can be defined by targets if they want total control over Index: gcc/llvm-convert.cpp =================================================================== --- gcc/llvm-convert.cpp (revision 230) +++ gcc/llvm-convert.cpp (working copy) @@ -206,7 +206,7 @@ ++AI; } - void HandleScalarArgument(const llvm::Type *LLVMTy) { + void HandleScalarArgument(const llvm::Type *LLVMTy, tree type) { Value *ArgVal = AI; if (ArgVal->getType() != LLVMTy) { // If this is just a mismatch between integer types, this could be due @@ -214,10 +214,9 @@ // the actual impls is a short or char. assert(ArgVal->getType()->isIntegral() && LLVMTy->isIntegral() && "Lowerings don't match?"); - Instruction::CastOps opcode = CastInst::getCastOpcode( - ArgVal, ArgVal->getType()->isSigned(), LLVMTy, LLVMTy->isSigned()); - ArgVal = - CastInst::create(opcode, ArgVal, LLVMTy, NameStack.back(), CurBB); + bool isSigned = type == 0 ? true : !TYPE_UNSIGNED(type); + ArgVal = CastInst::createIntegerCast(ArgVal, LLVMTy, isSigned, + NameStack.back(), CurBB); } assert(!LocStack.empty()); Value *Loc = LocStack.back(); @@ -424,14 +423,19 @@ if (!isAggregateTreeType(TREE_TYPE(DECL_RESULT(FnDecl)))) { // If the DECL_RESULT is a scalar type, just load out the return value // and return it. - RetVal = new LoadInst(DECL_LLVM(DECL_RESULT(FnDecl)), "retval", CurBB); - RetVal = CastToType(RetVal, Fn->getReturnType()); + tree TreeRetVal = DECL_RESULT(FnDecl); + RetVal = new LoadInst(DECL_LLVM(TreeRetVal), "retval", CurBB); + bool RetValSigned = !TYPE_UNSIGNED(TREE_TYPE(TreeRetVal)); + Instruction::CastOps opcode = CastInst::getCastOpcode( + RetVal, RetValSigned, Fn->getReturnType(), RetValSigned); + RetVal = CastToType(opcode, RetVal, Fn->getReturnType()); } else { // Otherwise, this aggregate result must be something that is returned in // a scalar register for this target. We must bit convert the aggregate // to the specified scalar type, which we do by casting the pointer and // loading. - RetVal = NOOPCastToType(DECL_LLVM(DECL_RESULT(FnDecl)), + RetVal = NOOPCastToType(Instruction::BitCast, + DECL_LLVM(DECL_RESULT(FnDecl)), PointerType::get(Fn->getReturnType())); RetVal = new LoadInst(RetVal, "retval", CurBB); } @@ -663,21 +667,66 @@ /// CastToType - Cast the specified value to the specified type if it is /// not already that type. -Value *TreeToLLVM::CastToType(Value *V, const Type *Ty) { - Instruction::CastOps opcode = CastInst::getCastOpcode( - V, V->getType()->isSigned(), Ty, Ty->isSigned()); +Value *TreeToLLVM::CastToType(unsigned opcode, Value *V, const Type* Ty) { if (V->getType() == Ty) return V; if (Constant *C = dyn_cast<Constant>(V)) - return ConstantExpr::getCast(opcode, C, Ty); + return ConstantExpr::getCast(Instruction::CastOps(opcode), C, Ty); // Handle cast (cast bool X to T2) to bool as X, because this occurs all over // the place. if (CastInst *CI = dyn_cast<CastInst>(V)) if (Ty == Type::BoolTy && CI->getOperand(0)->getType() == Type::BoolTy) return CI->getOperand(0); - return CastInst::create(opcode, V, Ty, V->getName(), CurBB); + return CastInst::create(Instruction::CastOps(opcode), V, Ty, V->getName(), + CurBB); } +/// CastToAnyType - Cast the specified value to the specified type making no +/// assumptions about the types of the arguments. This creates an inferred cast. +Value *TreeToLLVM::CastToAnyType(Value *V, bool VisSigned, + const Type* Ty, bool TyIsSigned) { + Instruction::CastOps opcode = CastInst::getCastOpcode(V, VisSigned, Ty, + TyIsSigned); + return CastToType(opcode, V, Ty); +} + +/// CastToUIntType - Cast the specified value to the specified type assuming +/// that the value and type are unsigned integer types. +Value *TreeToLLVM::CastToUIntType(Value *V, const Type* Ty) { + unsigned SrcBits = V->getType()->getPrimitiveSizeInBits(); + unsigned DstBits = Ty->getPrimitiveSizeInBits(); + Instruction::CastOps opcode = (SrcBits == DstBits ? Instruction::BitCast : + (SrcBits > DstBits ? Instruction::Trunc : Instruction::ZExt)); + return CastToType(opcode, V, Ty); +} + +/// CastToIntType - Cast the specified value to the specified type assuming +/// that the value and type are signed integer types. +Value *TreeToLLVM::CastToIntType(Value *V, const Type* Ty) { + unsigned SrcBits = V->getType()->getPrimitiveSizeInBits(); + unsigned DstBits = Ty->getPrimitiveSizeInBits(); + Instruction::CastOps opcode = (SrcBits == DstBits ? Instruction::BitCast : + (SrcBits > DstBits ? Instruction::Trunc : Instruction::SExt)); + return CastToType(opcode, V, Ty); +} + +/// CastToFPType - Cast the specified value to the specified type assuming +/// that the value and type or floating point +Value *TreeToLLVM::CastToFPType(Value *V, const Type* Ty) { + unsigned SrcBits = V->getType()->getPrimitiveSizeInBits(); + unsigned DstBits = Ty->getPrimitiveSizeInBits(); + Instruction::CastOps opcode = (SrcBits == DstBits ? Instruction::BitCast : + (SrcBits > DstBits ? Instruction::FPTrunc : Instruction::FPExt)); + return CastToType(opcode, V, Ty); +} + +/// NOOPCastToType - Insert a cast from V to Ty if needed. This checks that +/// the cast doesn't change the types in any value changing way. +Value *TreeToLLVM::NOOPCastToType(unsigned opcode, Value *V, const Type *Ty) { + assert(isNoopCast(V, Ty) && "This is not a noop cast!"); + return CastToType(Instruction::CastOps(opcode), V, Ty); +} + /// isNoopCast - Return true if a cast from V to Ty does not change any bits. /// bool TreeToLLVM::isNoopCast(Value *V, const Type *Ty) { @@ -812,8 +861,10 @@ TREE_INT_CST_LOW(TYPE_SIZE_UNIT(type)) < 64) { const Type *LLVMTy = ConvertType(type); if (CountAggregateElements(LLVMTy) <= 8) { - DestPtr = CastToType(DestPtr, PointerType::get(LLVMTy)); - SrcPtr = CastToType(SrcPtr, PointerType::get(LLVMTy)); + DestPtr = CastToType(Instruction::BitCast, DestPtr, + PointerType::get(LLVMTy)); + SrcPtr = CastToType(Instruction::BitCast, SrcPtr, + PointerType::get(LLVMTy)); // FIXME: Is this always safe? The LLVM type might theoretically have // holes or might be suboptimal to copy this way. It may be better to @@ -859,7 +910,8 @@ if (TREE_CODE(TYPE_SIZE(type)) == INTEGER_CST && TREE_INT_CST_LOW(TYPE_SIZE_UNIT(type)) < 128) { const Type *LLVMTy = ConvertType(type); - DestPtr = CastToType(DestPtr, PointerType::get(LLVMTy)); + DestPtr = CastToType(Instruction::BitCast, DestPtr, + PointerType::get(LLVMTy)); // FIXME: Is this always safe? The LLVM type might theoretically have holes // or might be suboptimal to copy this way. It may be better to copy the @@ -886,9 +938,9 @@ NULL); } std::vector<Value*> Ops; - Ops.push_back(CastToType(DestPtr, SBP)); - Ops.push_back(CastToType(SrcPtr, SBP)); - Ops.push_back(CastToType(Size, IntPtr)); + Ops.push_back(CastToType(Instruction::BitCast, DestPtr, SBP)); + Ops.push_back(CastToType(Instruction::BitCast, SrcPtr, SBP)); + Ops.push_back(CastToIntType(Size, IntPtr)); Ops.push_back(ConstantInt::get(Type::UIntTy, Align)); new CallInst(MemCpy, Ops, "", CurBB); } @@ -905,9 +957,9 @@ IntPtr, Type::UIntTy, NULL); } std::vector<Value*> Ops; - Ops.push_back(CastToType(DestPtr, SBP)); - Ops.push_back(CastToType(SrcPtr, SBP)); - Ops.push_back(CastToType(Size, IntPtr)); + Ops.push_back(CastToType(Instruction::BitCast, DestPtr, SBP)); + Ops.push_back(CastToType(Instruction::BitCast, SrcPtr, SBP)); + Ops.push_back(CastToIntType(Size, IntPtr)); Ops.push_back(ConstantInt::get(Type::UIntTy, Align)); new CallInst(MemMove, Ops, "", CurBB); } @@ -925,9 +977,9 @@ Type::UIntTy, NULL); } std::vector<Value*> Ops; - Ops.push_back(CastToType(DestPtr, SBP)); - Ops.push_back(CastToType(SrcVal, Type::UByteTy)); - Ops.push_back(CastToType(Size, IntPtr)); + Ops.push_back(CastToType(Instruction::BitCast, DestPtr, SBP)); + Ops.push_back(CastToIntType(SrcVal, Type::UByteTy)); + Ops.push_back(CastToIntType(Size, IntPtr)); Ops.push_back(ConstantInt::get(Type::UIntTy, Align)); new CallInst(MemSet, Ops, "", CurBB); } @@ -1098,7 +1150,7 @@ Ty = ConvertType(TREE_TYPE(type)); // Get array element type. // Compute the size of the number of elements of the array. Size = Emit(TYPE_MAX_VALUE(TYPE_DOMAIN(type)), 0); - Size = CastToType(Size, Type::UIntTy); + Size = CastToUIntType(Size, Type::UIntTy); // Annoyingly, TYPE_MAX_VALUE returns the maximum valid index, NOT the // number of elements in the array. Thus, we must add one to the returned @@ -1107,7 +1159,7 @@ "tmp", CurBB); } else { // Compute the variable's size in bytes. - Size = CastToType(Emit(DECL_SIZE_UNIT(decl), 0), Type::UIntTy); + Size = CastToUIntType(Emit(DECL_SIZE_UNIT(decl), 0), Type::UIntTy); Ty = Type::SByteTy; } } @@ -1281,7 +1333,7 @@ // Store the destination block to the GotoValue alloca. Value *V = Emit(TREE_OPERAND(exp, 0), 0); - V = CastToType(V, TD.getIntPtrType()); + V = CastToType(Instruction::PtrToInt, V, TD.getIntPtrType()); new StoreInst(V, IndirectGotoValue, CurBB); // NOTE: This is HORRIBLY INCORRECT in the presence of exception handlers. @@ -1314,9 +1366,11 @@ } Value *TreeToLLVM::EmitCOND_EXPR(tree exp) { - // Emit the conditional expression. - Value *Cond = EmitAsScalarType(COND_EXPR_COND(exp), Type::BoolTy); - + // Emit the conditional expression and trunc/bitcast to BoolTy + Value *Cond = Emit(COND_EXPR_COND(exp), 0); + Cond = new SetCondInst(Instruction::SetNE, Cond, + Constant::getNullValue(Cond->getType()), "toBool", + CurBB); tree Then = COND_EXPR_THEN(exp); tree Else = COND_EXPR_ELSE(exp); @@ -1425,7 +1479,7 @@ // Convert the integer to the right type. Value *Val = Emit(CASE_LOW(TREE_VEC_ELT(Cases, i)), 0); - Val = CastToType(Val, SwitchExp->getType()); + Val = CastToIntType(Val, SwitchExp->getType()); ConstantInt *ValC = cast<ConstantInt>(Val); if (CASE_HIGH(TREE_VEC_ELT(Cases, i)) == 0) { SI->addCase(ValC, Dest); // Single destination. @@ -1435,7 +1489,8 @@ // Otherwise, we have a range, like 'case 1 ... 17'. Add all of the // necessary successors to the switch. Val = Emit(CASE_HIGH(TREE_VEC_ELT(Cases, i)), 0); - Val = CastToType(Val, SwitchExp->getType()); + // Make sure the case value is the same type as the switch expression (int) + Val = CastToIntType(Val, SwitchExp->getType()); ConstantInt *HiC = cast<ConstantInt>(Val); Constant *OneC = ConstantInt::get(ValC->getType(), 1); while (1) { @@ -1693,13 +1748,14 @@ LValue LV = EmitLV(exp); bool isVolatile = TREE_THIS_VOLATILE(exp); + const Type *Ty = ConvertType(TREE_TYPE(exp)); if (!LV.isBitfield()) { - const Type *Ty = ConvertType(TREE_TYPE(exp)); if (!DestLoc) { // Scalar value: emit a load. - Value *Ptr = CastToType(LV.Ptr, PointerType::get(Ty)); + Value *Ptr = CastToType(Instruction::BitCast, LV.Ptr, + PointerType::get(Ty)); return new LoadInst(Ptr, "tmp", isVolatile, CurBB); } else { EmitAggregateCopy(DestLoc, LV.Ptr, TREE_TYPE(exp), false, isVolatile); @@ -1731,22 +1787,15 @@ // Shift right required? if (ValSizeInBits-LV.BitSize) { - // If this is an unsigned/signed bitfield reference and the LLVM value is - // signed/unsigned, cast to the appropriate signedness so that the shift - // coming up with do the right thing. - if (TYPE_UNSIGNED(TREE_TYPE(exp)) != Val->getType()->isUnsigned()) { - if (TYPE_UNSIGNED(TREE_TYPE(exp))) - Val = CastToType(Val, Val->getType()->getUnsignedVersion()); - else - Val = CastToType(Val, Val->getType()->getSignedVersion()); - } - Value *ShAmt = ConstantInt::get(Type::UByteTy, ValSizeInBits-LV.BitSize); Val = new ShiftInst( TYPE_UNSIGNED(TREE_TYPE(exp)) ? Instruction::LShr : Instruction::AShr, Val, ShAmt, "tmp", CurBB); } - - return CastToType(Val, ConvertType(TREE_TYPE(exp))); + + if (TYPE_UNSIGNED(TREE_TYPE(exp))) + return CastToUIntType(Val, Ty); + else + return CastToIntType(Val, Ty); } } @@ -1757,11 +1806,11 @@ // Perform a cast here if necessary. For example, GCC sometimes forms an // ADDR_EXPR where the operand is an array, and the ADDR_EXPR type is a // pointer to the first element. - return CastToType(LV.Ptr, ConvertType(TREE_TYPE(exp))); + return CastToType(Instruction::BitCast, LV.Ptr, ConvertType(TREE_TYPE(exp))); } Value *TreeToLLVM::EmitOBJ_TYPE_REF(tree exp) { - return CastToType(Emit(OBJ_TYPE_REF_EXPR(exp), 0), + return CastToType(Instruction::BitCast, Emit(OBJ_TYPE_REF_EXPR(exp), 0), ConvertType(TREE_TYPE(exp))); } @@ -1873,7 +1922,7 @@ CallOperands.push_back(DestLoc); } - void HandleScalarArgument(const llvm::Type *LLVMTy) { + void HandleScalarArgument(const llvm::Type *LLVMTy, tree type) { assert(!LocStack.empty()); Value *Loc = LocStack.back(); if (cast<PointerType>(Loc->getType())->getElementType() != LLVMTy) @@ -1956,10 +2005,11 @@ if (CallOperands.size() >= FTy->getNumParams()) ArgTy = PointerType::get(ArgTy); - CallOperands.push_back(CastToType(Ptr, ArgTy)); + CallOperands.push_back(CastToType(Instruction::BitCast, Ptr, ArgTy)); } else if (ActualArgTy->isFirstClassType()) { Value *V = Emit(TREE_VALUE(arg), 0); - CallOperands.push_back(CastToType(V, ArgTy)); + bool isSigned = !TYPE_UNSIGNED(TREE_TYPE(TREE_VALUE(arg))); + CallOperands.push_back(CastToAnyType(V, isSigned, ArgTy, false)); } else { // If this is an aggregate value passed by-value, use the current ABI to // determine how the parameters are passed. @@ -2009,7 +2059,8 @@ if (!DestLoc) return Call; // Normal scalar return. - DestLoc = NOOPCastToType(DestLoc, PointerType::get(Call->getType())); + DestLoc = NOOPCastToType(Instruction::BitCast, DestLoc, + PointerType::get(Call->getType())); new StoreInst(Call, DestLoc, CurBB); return 0; } @@ -2067,6 +2118,8 @@ Value *TreeToLLVM::EmitMODIFY_EXPR(tree exp, Value *DestLoc) { // If this is the definition of an SSA variable, set its DECL_LLVM to the // RHS. + bool Op0Signed = !TYPE_UNSIGNED(TREE_TYPE(TREE_OPERAND(exp, 0))); + bool Op1Signed = !TYPE_UNSIGNED(TREE_TYPE(TREE_OPERAND(exp, 1))); if (isGCC_SSA_Temporary(TREE_OPERAND(exp, 0))) { // If DECL_LLVM is already set, this is a multiply defined GCC temporary. if (DECL_LLVM_SET_P(TREE_OPERAND(exp, 0))) { @@ -2075,7 +2128,9 @@ } Value *RHS = Emit(TREE_OPERAND(exp, 1), 0); - RHS = CastToType(RHS, ConvertType(TREE_TYPE(TREE_OPERAND(exp, 0)))); + RHS = CastToAnyType(RHS, Op1Signed, + ConvertType(TREE_TYPE(TREE_OPERAND(exp, 0))), + Op0Signed); SET_DECL_LLVM(TREE_OPERAND(exp, 0), RHS); return RHS; } else if (TREE_CODE(TREE_OPERAND(exp, 0)) == VAR_DECL && @@ -2085,7 +2140,9 @@ // (there is no l-value of a register variable). Emit an inline asm node // that copies the value into the specified register. Value *RHS = Emit(TREE_OPERAND(exp, 1), 0); - RHS = CastToType(RHS, ConvertType(TREE_TYPE(TREE_OPERAND(exp, 0)))); + RHS = CastToAnyType(RHS, Op1Signed, + ConvertType(TREE_TYPE(TREE_OPERAND(exp, 0))), + Op0Signed); EmitModifyOfRegisterVariable(TREE_OPERAND(exp, 0), RHS); return RHS; } @@ -2101,9 +2158,10 @@ // Convert RHS to the right type if we can, otherwise convert the pointer. const PointerType *PT = cast<PointerType>(LV.Ptr->getType()); if (PT->getElementType()->canLosslesslyBitCastTo(RHS->getType())) - RHS = CastToType(RHS, PT->getElementType()); + RHS = CastToAnyType(RHS, Op1Signed, PT->getElementType(), Op0Signed); else - LV.Ptr = NOOPCastToType(LV.Ptr, PointerType::get(RHS->getType()));; + LV.Ptr = NOOPCastToType(Instruction::BitCast, LV.Ptr, + PointerType::get(RHS->getType())); new StoreInst(RHS, LV.Ptr, isVolatile, CurBB); return RHS; } @@ -2127,7 +2185,7 @@ // If not storing into the zero'th bit, shift the Src value to the left. Value *RHS = Emit(TREE_OPERAND(exp, 1), 0); Value *RetVal = RHS; - RHS = CastToType(RHS, OldVal->getType()); + RHS = CastToAnyType(RHS, Op1Signed, OldVal->getType(), Op0Signed); if (LV.BitStart) RHS = new ShiftInst(Instruction::Shl, RHS, ConstantInt::get(Type::UByteTy, LV.BitStart), @@ -2156,31 +2214,36 @@ return 0; tree Op = TREE_OPERAND(exp, 0); const Type *Ty = ConvertType(TREE_TYPE(exp)); + bool OpIsSigned = !TYPE_UNSIGNED(TREE_TYPE(Op)); + bool ExpIsSigned = !TYPE_UNSIGNED(TREE_TYPE(exp)); if (DestLoc == 0) { // Scalar to scalar copy. assert(!isAggregateType(TREE_TYPE(Op)) && "Aggregate to scalar nop_expr!"); Value *OpVal = Emit(Op, DestLoc); if (Ty == Type::VoidTy) return 0; - return CastToType(OpVal, Ty); + return CastToAnyType(OpVal, OpIsSigned, Ty, ExpIsSigned); } else if (isAggregateType(TREE_TYPE(Op))) { // Aggregate to aggregate copy. - DestLoc = CastToType(DestLoc, PointerType::get(Ty)); + DestLoc = CastToType(Instruction::BitCast, DestLoc, PointerType::get(Ty)); Value *OpVal = Emit(Op, DestLoc); assert(OpVal == 0 && "Shouldn't cast scalar to aggregate!"); return 0; - } else { - // Scalar to aggregate copy. - Value *OpVal = Emit(Op, 0); - DestLoc = CastToType(DestLoc, PointerType::get(OpVal->getType())); - new StoreInst(OpVal, DestLoc, CurBB); - return 0; - } + } + + // Scalar to aggregate copy. + Value *OpVal = Emit(Op, 0); + DestLoc = CastToType(Instruction::BitCast, DestLoc, + PointerType::get(OpVal->getType())); + new StoreInst(OpVal, DestLoc, CurBB); + return 0; } Value *TreeToLLVM::EmitCONVERT_EXPR(tree exp, Value *DestLoc) { assert(!DestLoc && "Cannot handle aggregate casts!"); Value *Op = Emit(TREE_OPERAND(exp, 0), 0); - return CastToType(Op, ConvertType(TREE_TYPE(exp))); + bool OpIsSigned = !TYPE_UNSIGNED(TREE_TYPE(TREE_OPERAND(exp, 0))); + bool ExpIsSigned = !TYPE_UNSIGNED(TREE_TYPE(exp)); + return CastToAnyType(Op, OpIsSigned, ConvertType(TREE_TYPE(exp)),ExpIsSigned); } Value *TreeToLLVM::EmitVIEW_CONVERT_EXPR(tree exp, Value *DestLoc) { @@ -2190,7 +2253,8 @@ if (isAggregateType(TREE_TYPE(Op))) { if (DestLoc) { // This is an aggregate-to-agg VIEW_CONVERT_EXPR, just evaluate in place. - Value *OpVal = Emit(Op, CastToType(DestLoc, PointerType::get(OpTy))); + Value *OpVal = Emit(Op, CastToType(Instruction::BitCast, DestLoc, + PointerType::get(OpTy))); assert(OpVal == 0 && "Expected an aggregate operand!"); return 0; } else { @@ -2200,8 +2264,8 @@ assert(OpVal == 0 && "Expected an aggregate operand!"); const Type *ExpTy = ConvertType(TREE_TYPE(exp)); - return new LoadInst(CastToType(DestLoc, PointerType::get(ExpTy)), "tmp", - CurBB); + return new LoadInst(CastToType(Instruction::BitCast, DestLoc, + PointerType::get(ExpTy)), "tmp", CurBB); } } @@ -2210,7 +2274,8 @@ // then store into DestLoc. Value *OpVal = Emit(Op, 0); assert(OpVal && "Expected a scalar result!"); - DestLoc = CastToType(DestLoc, PointerType::get(OpVal->getType())); + DestLoc = CastToType(Instruction::BitCast, DestLoc, + PointerType::get(OpVal->getType())); new StoreInst(OpVal, DestLoc, CurBB); return 0; } @@ -2292,9 +2357,10 @@ Value *TreeToLLVM::EmitTRUTH_NOT_EXPR(tree exp) { Value *V = Emit(TREE_OPERAND(exp, 0), 0); - V = CastToType(V, Type::BoolTy); + V = new SetCondInst(Instruction::SetNE, V, + Constant::getNullValue(V->getType()), "toBool", CurBB); V = BinaryOperator::createNot(V, V->getName()+"not", CurBB); - return CastToType(V, TREE_TYPE(exp)); + return CastToUIntType(V, ConvertType(TREE_TYPE(exp))); } /// EmitCompare - 'exp' is a comparison of two values. Opc is the base LLVM @@ -2308,7 +2374,9 @@ // Comparison of struct is not allowed, so this is safe. Value *LHS = Emit(TREE_OPERAND(exp, 0), 0); Value *RHS = Emit(TREE_OPERAND(exp, 1), 0); - RHS = NOOPCastToType(RHS, LHS->getType()); + bool LHSIsSigned = !TYPE_UNSIGNED(TREE_TYPE(TREE_OPERAND(exp, 0))); + bool RHSIsSigned = !TYPE_UNSIGNED(TREE_TYPE(TREE_OPERAND(exp, 1))); + RHS = CastToAnyType(RHS, RHSIsSigned, LHS->getType(), LHSIsSigned); assert(LHS->getType() == RHS->getType() && "Binop type equality failure!"); @@ -2340,7 +2408,7 @@ } // The GCC type is probably an int, not a bool. - return CastToType(Result, ConvertType(TREE_TYPE(exp))); + return CastToUIntType(Result, ConvertType(TREE_TYPE(exp))); } /// EmitBinOp - 'exp' is a binary operator. @@ -2360,8 +2428,11 @@ // GCC has no problem with things like "xor uint X, int 17", and X-Y, where // X and Y are pointer types, but the result is an integer. As such, convert // everything to the result type. - LHS = NOOPCastToType(LHS, Ty); - RHS = NOOPCastToType(RHS, Ty); + bool LHSIsSigned = !TYPE_UNSIGNED(TREE_TYPE(TREE_OPERAND(exp, 0))); + bool RHSIsSigned = !TYPE_UNSIGNED(TREE_TYPE(TREE_OPERAND(exp, 1))); + bool TyIsSigned = !TYPE_UNSIGNED(TREE_TYPE(exp)); + LHS = CastToAnyType(LHS, LHSIsSigned, Ty, TyIsSigned); + RHS = CastToAnyType(RHS, RHSIsSigned, Ty, TyIsSigned); return BinaryOperator::create((Instruction::BinaryOps)Opc, LHS, RHS, "tmp", CurBB); @@ -2398,7 +2469,7 @@ EltOffset = -EltOffset; Constant *C = ConstantInt::get(Type::LongTy, EltOffset); Value *V = new GetElementPtrInst(LHS, C, "tmp", CurBB); - return CastToType(V, TREE_TYPE(exp)); + return CastToType(Instruction::BitCast, V, TREE_TYPE(exp)); } } } @@ -2407,25 +2478,34 @@ Value *RHS = Emit(TREE_OPERAND(exp, 1), 0); const Type *UIntPtrTy = TD.getIntPtrType(); - LHS = CastToType(LHS, UIntPtrTy); - RHS = CastToType(RHS, UIntPtrTy); + bool LHSIsSigned = !TYPE_UNSIGNED(TREE_TYPE(TREE_OPERAND(exp, 0))); + bool RHSIsSigned = !TYPE_UNSIGNED(TREE_TYPE(TREE_OPERAND(exp, 1))); + LHS = CastToAnyType(LHS, LHSIsSigned, UIntPtrTy, false); + RHS = CastToAnyType(RHS, RHSIsSigned, UIntPtrTy, false); Value *V = BinaryOperator::create((Instruction::BinaryOps)Opc, LHS, RHS, "tmp", CurBB); - return CastToType(V, TREE_TYPE(exp)); + return CastToType(Instruction::IntToPtr, V, ConvertType(TREE_TYPE(exp))); } Value *TreeToLLVM::EmitTruthOp(tree exp, unsigned Opc) { Value *LHS = Emit(TREE_OPERAND(exp, 0), 0); Value *RHS = Emit(TREE_OPERAND(exp, 1), 0); + bool LHSIsSigned = !TYPE_UNSIGNED(TREE_TYPE(TREE_OPERAND(exp, 0))); + bool RHSIsSigned = !TYPE_UNSIGNED(TREE_TYPE(TREE_OPERAND(exp, 1))); - // This is a truth operation like the strict &&,||,^^. Convert to bool. - LHS = CastToType(LHS, Type::BoolTy); - RHS = CastToType(RHS, Type::BoolTy); + // This is a truth operation like the strict &&,||,^^. Convert to bool as + // a test against zero + LHS = new SetCondInst(Instruction::SetNE, LHS, + Constant::getNullValue(LHS->getType()), + "toBool", CurBB); + RHS = new SetCondInst(Instruction::SetNE, RHS, + Constant::getNullValue(RHS->getType()), + "toBool", CurBB); Value *Res = BinaryOperator::create((Instruction::BinaryOps)Opc, LHS, RHS, "tmp", CurBB); - return CastToType(Res, ConvertType(TREE_TYPE(exp))); + return CastToType(Instruction::ZExt, Res, ConvertType(TREE_TYPE(exp))); } @@ -2436,26 +2516,15 @@ Value *LHS = Emit(TREE_OPERAND(exp, 0), 0); Value *RHS = Emit(TREE_OPERAND(exp, 1), 0); - RHS = CastToType(RHS, Type::UByteTy); + RHS = CastToUIntType(RHS, Type::UByteTy); - if (TYPE_UNSIGNED(TREE_TYPE(exp)) != LHS->getType()->isUnsigned()) { - if (TYPE_UNSIGNED(TREE_TYPE(exp))) - LHS = CastToType(LHS, LHS->getType()->getUnsignedVersion()); - else - LHS = CastToType(LHS, LHS->getType()->getSignedVersion()); - } - - return new ShiftInst((Instruction::OtherOps)Opc, LHS, RHS, - "tmp", CurBB); + return new ShiftInst((Instruction::OtherOps)Opc, LHS, RHS, "tmp", CurBB); } Value *TreeToLLVM::EmitRotateOp(tree exp, unsigned Opc1, unsigned Opc2) { Value *In = Emit(TREE_OPERAND(exp, 0), 0); - Value *Amt = CastToType(Emit(TREE_OPERAND(exp, 1), 0), Type::UByteTy); + Value *Amt = CastToUIntType(Emit(TREE_OPERAND(exp, 1), 0), Type::UByteTy); - // Make sure that the value is an unsigned type, so that we do a logical shr. - In = CastToType(In, In->getType()->getUnsignedVersion()); - Value *TypeSize = ConstantInt::get(Type::UByteTy, In->getType()->getPrimitiveSizeInBits()); @@ -2467,7 +2536,7 @@ // Or the two together to return them. Value *Merge = BinaryOperator::createOr(V1, V2, "tmp", CurBB); - return CastToType(Merge, ConvertType(TREE_TYPE(exp))); + return CastToUIntType(Merge, ConvertType(TREE_TYPE(exp))); } Value *TreeToLLVM::EmitMinMaxExpr(tree exp, unsigned CmpOpc) { @@ -2475,8 +2544,18 @@ Value *RHS = Emit(TREE_OPERAND(exp, 1), 0); const Type *Ty = ConvertType(TREE_TYPE(exp)); - LHS = NOOPCastToType(LHS, Ty); - RHS = NOOPCastToType(RHS, Ty); + + // The LHS, RHS and Ty could be integer, floating or pointer typed. We need + // to convert the LHS and RHS into the destination type before doing the + // comparison. Use CastInst::getCastOpcode to get this right. + bool TyIsSigned = !TYPE_UNSIGNED(TREE_TYPE(exp)); + bool LHSIsSigned = !TYPE_UNSIGNED(TREE_TYPE(TREE_OPERAND(exp, 0))); + bool RHSIsSigned = !TYPE_UNSIGNED(TREE_TYPE(TREE_OPERAND(exp, 1))); + Instruction::CastOps opcode = CastInst::getCastOpcode(LHS, LHSIsSigned, Ty, + TyIsSigned); + LHS = NOOPCastToType(opcode, LHS, Ty); + opcode = CastInst::getCastOpcode(LHS, LHSIsSigned, Ty, TyIsSigned); + RHS = NOOPCastToType(opcode, RHS, Ty); Value *Pred = new SetCondInst((Instruction::BinaryOps)CmpOpc, LHS, RHS, "tmp", CurBB); @@ -3137,7 +3216,7 @@ if (!flag_errno_math) { Value *Amt = Emit(TREE_VALUE(TREE_OPERAND(exp, 1)), 0); HANDLE_UNARY_FP("llvm.sqrt.f32", "llvm.sqrt.f64", Amt); - Result = CastToType(Result, ConvertType(TREE_TYPE(exp))); + Result = CastToFPType(Result, ConvertType(TREE_TYPE(exp))); return true; } break; @@ -3213,8 +3292,9 @@ // Integer Intrinsics only come in one version for each integer size, and we // have standardized on unsigned operands. Convert the operand to unsigned // if it is signed. + // FIXME: Remove this when signedness goes away. if (InVal->getType()->isSigned()) - InVal = CastToType(InVal, InVal->getType()->getUnsignedVersion()); + InVal = CastToUIntType(InVal, InVal->getType()->getUnsignedVersion()); const char *Name; Function **FCache; @@ -3233,7 +3313,7 @@ // The LLVM intrinsics for these return the same type as their operands. The // GCC version of these functions always returns int. Cast to int for GCC. - Result = CastToType(Result, Type::IntTy); + Result = CastToIntType(Result, Type::IntTy); return true; } @@ -3263,7 +3343,7 @@ Value *Val = Emit(TREE_VALUE(ArgList), 0); Value *Pow = Emit(TREE_VALUE(TREE_CHAIN(ArgList)), 0); - Pow = CastToType(Pow, Type::IntTy); + Pow = CastToIntType(Pow, Type::IntTy); static Function *Fn32 = 0, *Fn64 = 0; const char *Name; @@ -3290,7 +3370,10 @@ bool TreeToLLVM::EmitBuiltinExtendPointer(tree exp, Value *&Result) { tree arglist = TREE_OPERAND(exp, 1); Value *Amt = Emit(TREE_VALUE(arglist), 0); - Result = CastToType(Amt, ConvertType(TREE_TYPE(exp))); + bool AmtIsSigned = !TYPE_UNSIGNED(TREE_TYPE(TREE_VALUE(arglist))); + bool ExpIsSigned = !TYPE_UNSIGNED(TREE_TYPE(exp)); + Result = CastToAnyType(Amt, AmtIsSigned, ConvertType(TREE_TYPE(exp)), + ExpIsSigned); return true; } @@ -3404,7 +3487,7 @@ if (Locality == 0) Locality = ConstantInt::get(Type::UIntTy, 3); - Ptr = CastToType(Ptr, PointerType::get(Type::SByteTy)); + Ptr = CastToType(Instruction::BitCast, Ptr, PointerType::get(Type::SByteTy)); static Function *llvm_prefetch_fn = 0; if (!llvm_prefetch_fn) @@ -3456,7 +3539,7 @@ } Result = new CallInst(Fn, Level, "tmp", CurBB); - Result = CastToType(Result, TREE_TYPE(exp)); + Result = CastToType(Instruction::BitCast, Result, TREE_TYPE(exp)); return true; } @@ -3483,7 +3566,7 @@ Fn = TheModule->getOrInsertFunction("llvm.stackrestore", Type::VoidTy, PointerType::get(Type::SByteTy), NULL); Value *Ptr = Emit(TREE_VALUE(arglist), 0); - Ptr = CastToType(Ptr, PointerType::get(Type::SByteTy)); + Ptr = CastToType(Instruction::BitCast, Ptr, PointerType::get(Type::SByteTy)); new CallInst(Fn, Ptr, "", CurBB); return true; @@ -3495,7 +3578,7 @@ if (!validate_arglist(arglist, INTEGER_TYPE, VOID_TYPE)) return false; Value *Amt = Emit(TREE_VALUE(arglist), 0); - Amt = CastToType(Amt, Type::UIntTy); + Amt = CastToIntType(Amt, Type::UIntTy); Result = new AllocaInst(Type::SByteTy, Amt, "tmp", CurBB); return true; } @@ -3543,7 +3626,8 @@ Value *ArgVal = Emit(TREE_VALUE(arglist), 0); const Type *FTy = llvm_va_start_fn->getType()->getElementType(); - ArgVal = CastToType(ArgVal, cast<FunctionType>(FTy)->getParamType(0)); + ArgVal = CastToType(Instruction::BitCast, ArgVal, + cast<FunctionType>(FTy)->getParamType(0)); new CallInst(llvm_va_start_fn, ArgVal, "", CurBB); return true; } @@ -3559,7 +3643,8 @@ Value *Arg = Emit(TREE_VALUE(TREE_OPERAND(exp, 1)), 0); const Type *FTy = llvm_va_end_fn->getType()->getElementType(); - Arg = CastToType(Arg, cast<FunctionType>(FTy)->getParamType(0)); + Arg = CastToType(Instruction::BitCast, Arg, + cast<FunctionType>(FTy)->getParamType(0)); new CallInst(llvm_va_end_fn, Arg, "", CurBB); return true; @@ -3598,8 +3683,8 @@ const Type *FTy = llvm_va_copy_fn->getType()->getElementType(); const Type *PtrList = cast<FunctionType>(FTy)->getParamType(0); - Arg1 = CastToType(Arg1, PtrList); - Arg2 = CastToType(Arg2, PtrList); + Arg1 = CastToType(Instruction::BitCast, Arg1, PtrList); + Arg2 = CastToType(Instruction::BitCast, Arg2, PtrList); new CallInst(llvm_va_copy_fn, Arg1, Arg2, "", CurBB); return true; @@ -3789,7 +3874,7 @@ if (Ty == Type::VoidTy) Ty = StructType::get(std::vector<const Type*>(), false); const PointerType *PTy = PointerType::get(Ty); - return CastToType(Decl, PTy); + return CastToType(Instruction::BitCast, Decl, PTy); } LValue TreeToLLVM::EmitLV_INDIRECT_REF(tree exp) { @@ -3832,7 +3917,7 @@ IndexVal->getType() != Type::UIntTy && IndexVal->getType() != Type::LongTy && IndexVal->getType() != Type::ULongTy) - IndexVal = CastToType(IndexVal, Type::LongTy); + IndexVal = CastToType(Instruction::SExt, IndexVal, Type::LongTy); // Check for variable sized array reference. if (TREE_CODE(TREE_TYPE(Array)) == ARRAY_TYPE) { @@ -3882,7 +3967,8 @@ assert((!StructAddrLV.isBitfield() || StructAddrLV.BitStart == 0) && "structs cannot be bitfields!"); - StructAddrLV.Ptr = CastToType(StructAddrLV.Ptr, PointerType::get(StructTy)); + StructAddrLV.Ptr = CastToType(Instruction::BitCast, StructAddrLV.Ptr, + PointerType::get(StructTy)); const Type *FieldTy = ConvertType(TREE_TYPE(FieldDecl)); // BitStart - This is the actual offset of the field from the start of the @@ -3917,9 +4003,10 @@ } else { Value *Offset = Emit(DECL_FIELD_OFFSET(FieldDecl), 0); - Value *Ptr = CastToType(StructAddrLV.Ptr, Offset->getType()); + Value *Ptr = CastToType(Instruction::PtrToInt, StructAddrLV.Ptr, + Offset->getType()); Ptr = BinaryOperator::createAdd(Ptr, Offset, "tmp", CurBB); - FieldPtr = CastToType(Ptr, PointerType::get(FieldTy)); + FieldPtr = CastToType(Instruction::IntToPtr, Ptr,PointerType::get(FieldTy)); } if (tree DeclaredType = DECL_BIT_FIELD_TYPE(FieldDecl)) { @@ -3951,11 +4038,13 @@ // a store to B. In this case, without this conversion, you'd have a // store through an int*, followed by a load from a uint*. Forcing them // both to uint* allows the store to be forwarded to the load. + // FIXME: Remove this when signedness goes away FieldTy = FieldTy->getUnsignedVersion(); // If this is a bitfield, the field may span multiple fields in the LLVM // type. As such, cast the pointer to be a pointer to the declared type. - FieldPtr = CastToType(FieldPtr, PointerType::get(FieldTy)); + FieldPtr = CastToType(Instruction::BitCast, FieldPtr, + PointerType::get(FieldTy)); // If this is a normal bitfield reference, return it as such. if (DECL_SIZE(FieldDecl) && TREE_CODE(DECL_SIZE(FieldDecl)) == INTEGER_CST){ @@ -3981,9 +4070,11 @@ unsigned ByteOffset = NumAlignmentUnits*ByteAlignment; Constant *Offset = ConstantInt::get(TD.getIntPtrType(), ByteOffset); - FieldPtr = CastToType(FieldPtr, Offset->getType()); + FieldPtr = CastToType(Instruction::PtrToInt, FieldPtr, + Offset->getType()); FieldPtr = BinaryOperator::createAdd(FieldPtr, Offset, "tmp", CurBB); - FieldPtr = CastToType(FieldPtr, PointerType::get(FieldTy)); + FieldPtr = CastToType(Instruction::IntToPtr, FieldPtr, + PointerType::get(FieldTy)); // Adjust bitstart to account for the pointer movement. BitStart -= ByteOffset*8; @@ -4001,7 +4092,7 @@ } } else { // Make sure we return a pointer to the right type. - FieldPtr = CastToType(FieldPtr, + FieldPtr = CastToType(Instruction::BitCast, FieldPtr, PointerType::get(ConvertType(TREE_TYPE(exp)))); } @@ -4029,7 +4120,8 @@ if (unsigned UnitOffset = BitStart / ValueSizeInBits) { // TODO: If Ptr.Ptr is a struct type or something, we can do much better // than this. e.g. check out when compiling unwind-dw2-fde-darwin.c. - Ptr.Ptr = CastToType(Ptr.Ptr, PointerType::get(ValTy)); + Ptr.Ptr = CastToType(Instruction::BitCast, Ptr.Ptr, + PointerType::get(ValTy)); Ptr.Ptr = new GetElementPtrInst(Ptr.Ptr, ConstantInt::get(Type::UIntTy, UnitOffset), "tmp", CurBB); @@ -4038,10 +4130,11 @@ // If this is referring to the whole field, return the whole thing. if (BitStart == 0 && BitSize == ValueSizeInBits) - return LValue(NOOPCastToType(Ptr.Ptr, PointerType::get(ValTy))); + return LValue(NOOPCastToType(Instruction::BitCast, Ptr.Ptr, + PointerType::get(ValTy))); - return LValue(NOOPCastToType(Ptr.Ptr, PointerType::get(ValTy)), - BitStart, BitSize); + return LValue(NOOPCastToType(Instruction::BitCast, Ptr.Ptr, + PointerType::get(ValTy)), BitStart, BitSize); } LValue TreeToLLVM::EmitLV_XXXXPART_EXPR(tree exp, unsigned Idx) { @@ -4114,7 +4207,8 @@ } else { // Scalar value. Evaluate to a register, then do the store. Value *V = Emit(TREE_VALUE(elt), 0); - DestLoc = CastToType(DestLoc, PointerType::get(V->getType())); + DestLoc = CastToType(Instruction::BitCast, DestLoc, + PointerType::get(V->getType())); new StoreInst(V, DestLoc, CurBB); } break; @@ -4160,8 +4254,10 @@ // type. This handles overflow and other things appropriately. const Type *Ty = ConvertType(TREE_TYPE(exp)); ConstantInt *C = ConstantInt::get(Type::ULongTy, IntValue); - Instruction::CastOps opcode = CastInst::getCastOpcode( - C, false, Ty, Ty->isSigned()); + // The destination type can be a pointer, integer or floating point + // so we need a generalized cast here + Instruction::CastOps opcode = CastInst::getCastOpcode(C, false, Ty, + !TYPE_UNSIGNED(TREE_TYPE(exp))); return ConstantExpr::getCast(opcode, C, Ty); } @@ -4278,29 +4374,35 @@ Constant *TreeConstantToLLVM::ConvertNOP_EXPR(tree exp) { Constant *Elt = Convert(TREE_OPERAND(exp, 0)); const Type *Ty = ConvertType(TREE_TYPE(exp)); - Instruction::CastOps opcode = CastInst::getCastOpcode( - Elt, Elt->getType()->isSigned(), Ty, Ty->isSigned()); + bool EltIsSigned = !TYPE_UNSIGNED(TREE_TYPE(TREE_OPERAND(exp, 0))); + bool TyIsSigned = !TYPE_UNSIGNED(TREE_TYPE(exp)); + // Elt and Ty can be integer, float or pointer here: need generalized cast + Instruction::CastOps opcode = CastInst::getCastOpcode(Elt, EltIsSigned, + Ty, TyIsSigned); return ConstantExpr::getCast(opcode, Elt, Ty); } Constant *TreeConstantToLLVM::ConvertCONVERT_EXPR(tree exp) { Constant *Elt = Convert(TREE_OPERAND(exp, 0)); + bool EltIsSigned = !TYPE_UNSIGNED(TREE_TYPE(TREE_OPERAND(exp, 0))); const Type *Ty = ConvertType(TREE_TYPE(exp)); - Instruction::CastOps opcode = CastInst::getCastOpcode( - Elt, Elt->getType()->isSigned(), Ty, Ty->isSigned()); + bool TyIsSigned = !TYPE_UNSIGNED(TREE_TYPE(exp)); + Instruction::CastOps opcode = CastInst::getCastOpcode(Elt, EltIsSigned, Ty, + TyIsSigned); return ConstantExpr::getCast(opcode, Elt, Ty); } Constant *TreeConstantToLLVM::ConvertBinOp_CST(tree exp) { Constant *LHS = Convert(TREE_OPERAND(exp, 0)); + bool LHSIsSigned = !TYPE_UNSIGNED(TREE_TYPE(TREE_OPERAND(exp,0))); Constant *RHS = Convert(TREE_OPERAND(exp, 1)); + bool RHSIsSigned = !TYPE_UNSIGNED(TREE_TYPE(TREE_OPERAND(exp,1))); + Instruction::CastOps opcode; if (isa<PointerType>(LHS->getType())) { const Type *UIntPtrTy = getTargetData().getIntPtrType(); - Instruction::CastOps opcode = CastInst::getCastOpcode( - LHS, LHS->getType()->isSigned(), UIntPtrTy, false); + opcode = CastInst::getCastOpcode(LHS, LHSIsSigned, UIntPtrTy, false); LHS = ConstantExpr::getCast(opcode, LHS, UIntPtrTy); - opcode = CastInst::getCastOpcode(RHS, RHS->getType()->isSigned(), - UIntPtrTy, false); + opcode = CastInst::getCastOpcode(RHS, RHSIsSigned, UIntPtrTy, false); RHS = ConstantExpr::getCast(opcode, RHS, UIntPtrTy); } @@ -4312,8 +4414,8 @@ } const Type *Ty = ConvertType(TREE_TYPE(exp)); - Instruction::CastOps opcode = CastInst::getCastOpcode( - Result, Result->getType()->isSigned(), Ty, Ty->isSigned()); + bool TyIsSigned = !TYPE_UNSIGNED(TREE_TYPE(exp)); + opcode = CastInst::getCastOpcode(Result, LHSIsSigned, Ty, TyIsSigned); return ConstantExpr::getCast(opcode, Result, Ty); } Index: gcc/llvm-internal.h =================================================================== --- gcc/llvm-internal.h (revision 230) +++ gcc/llvm-internal.h (working copy) @@ -294,18 +294,34 @@ /// CastToType - Cast the specified value to the specified type if it is /// not already that type. - Value *CastToType(Value *V, const Type *Ty); - Value *CastToType(Value *V, tree_node *type) { - return CastToType(V, ConvertType(type)); + Value *CastToType(unsigned opcode, Value *V, const Type *Ty); + Value *CastToType(unsigned opcode, Value *V, tree_node *type) { + return CastToType(opcode, V, ConvertType(type)); } + /// CastToAnyType - Cast the specified value to the specified type regardless + /// of the types involved. This is an inferred cast. + Value *CastToAnyType (Value *V, bool VSigned, const Type* Ty, bool TySigned); + + /// CastToUIntTYpe - Cast the specified value to the specified type assuming + /// that V's type and Ty are integral types. This arbitrates between BitCast, + /// Trunc and ZExt. + Value *CastToUIntType(Value *V, const Type* Ty); + + /// CastToUIntTYpe - Cast the specified value to the specified type assuming + /// that V's type and Ty are integral types. This arbitrates between BitCast, + /// Trunc and SExt. + Value *CastToIntType (Value *V, const Type* Ty); + + /// CastToFPTYpe - Cast the specified value to the specified type assuming + /// that V's type and Ty are floating point types. This arbitrates between + /// BitCast, FPTrunc and FPExt. + Value *CastToFPType (Value *V, const Type* Ty); + /// NOOPCastToType - Insert a cast from V to Ty if needed. This checks that /// the cast doesn't change the types in any value changing way. - Value *NOOPCastToType(Value *V, const Type *Ty) { - assert(isNoopCast(V, Ty) && "This is not a noop cast!"); - return CastToType(V, Ty); - } - + Value *NOOPCastToType(unsigned opcode, Value *V, const Type *Ty); + /// CreateTemporary - Create a new alloca instruction of the specified type, /// inserting it into the entry block and returning it. The resulting /// instruction's type is a pointer to the specified type. @@ -313,12 +329,6 @@ private: // Helper functions. - /// EmitAsScalarType - Call Emit to output an expression which generates a - /// scalar value, then convert it to the specified type if it is not already. - Value *EmitAsScalarType(tree_node *exp, const Type *Ty) { - return CastToType(Emit(exp, 0), Ty); - } - /// EmitBlock - Add the specified basic block to the end of the function. If /// the previous block falls through into it, add an explicit branch. Also, /// manage fixups for EH info. Index: gcc/llvm-types.cpp =================================================================== --- gcc/llvm-types.cpp (revision 230) +++ gcc/llvm-types.cpp (working copy) @@ -390,8 +390,8 @@ // If we are converting a struct, and if we haven't converted the pointee // type, add this pointer to PointersToReresolve and return an opaque*. if (ConvertingStruct) { - // If the pointee type has not already been converted to LLVM, create a new - // opaque type and remember it in the database. + // If the pointee type has not already been converted to LLVM, create + // a new opaque type and remember it in the database. Ty = GET_TYPE_LLVM(TYPE_MAIN_VARIANT(TREE_TYPE(type))); if (Ty == 0) { PointersToReresolve.push_back(type); @@ -399,15 +399,15 @@ } // A type has already been computed. However, this may be some sort of - // recursive struct. We don't want to call ConvertType on it, because this - // will try to resolve it, and not adding the type to the PointerToReresolve - // collection is just an optimization. Instead, we'll use the type returned - // by GET_TYPE_LLVM directly, even if this may be resolved further in the - // future. + // recursive struct. We don't want to call ConvertType on it, because + // this will try to resolve it, and not adding the type to the + // PointerToReresolve collection is just an optimization. Instead, + // we'll use the type returned by GET_TYPE_LLVM directly, even if this + // may be resolved further in the future. } else { - // If we're not in a struct, just call ConvertType. If it has already been - // converted, this will return the precomputed value, otherwise this will - // compute and return the new type. + // If we're not in a struct, just call ConvertType. If it has already + // been converted, this will return the precomputed value, otherwise + // this will compute and return the new type. Ty = ConvertType(TREE_TYPE(type)); } @@ -495,8 +495,9 @@ } /// HandleAggregateShadowArgument - This callback is invoked if the function - /// returns an aggregate value by using a "shadow" first parameter. If RetPtr - /// is set to true, the pointer argument itself is returned from the function. + /// returns an aggregate value by using a "shadow" first parameter. If + /// RetPtr is set to true, the pointer argument itself is returned from + /// the function. void HandleAggregateShadowArgument(const PointerType *PtrArgTy, bool RetPtr) { // If this function returns a structure by value, it either returns void @@ -510,7 +511,7 @@ CallingConv = CallingConv::CSRet; } - void HandleScalarArgument(const llvm::Type *LLVMTy) { + void HandleScalarArgument(const llvm::Type *LLVMTy, tree type) { ArgTypes.push_back(LLVMTy); } };
_______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits