Index: llvm/docs/ReleaseNotes.rst =================================================================== --- llvm/docs/ReleaseNotes.rst +++ llvm/docs/ReleaseNotes.rst @@ -130,6 +130,9 @@ * ``LLVMSetInstDebugLocation`` has been deprecated in favor of the more general ``LLVMAddMetadataToInst``. +* Add ``LLVMGetCastOpcode`` function to aid users of ``LLVMBuildCast`` in + resolving the best cast operation given a source value and destination type. + This function is a direct wrapper of ``CastInst::getCastOpcode``. Changes to the Go bindings -------------------------- Index: llvm/include/llvm-c/Core.h =================================================================== --- llvm/include/llvm-c/Core.h +++ llvm/include/llvm-c/Core.h @@ -3950,6 +3950,9 @@ LLVMValueRef LLVMBuildIntCast(LLVMBuilderRef, LLVMValueRef Val, /*Signed cast!*/ LLVMTypeRef DestTy, const char *Name); +LLVMOpcode LLVMGetCastOpcode(LLVMValueRef Src, LLVMBool SrcIsSigned, + LLVMTypeRef DestTy, LLVMBool DestIsSigned); + /* Comparisons */ LLVMValueRef LLVMBuildICmp(LLVMBuilderRef, LLVMIntPredicate Op, LLVMValueRef LHS, LLVMValueRef RHS, Index: llvm/lib/IR/Core.cpp =================================================================== --- llvm/lib/IR/Core.cpp +++ llvm/lib/IR/Core.cpp @@ -3891,6 +3891,12 @@ return wrap(unwrap(B)->CreateFPCast(unwrap(Val), unwrap(DestTy), Name)); } +LLVMOpcode LLVMGetCastOpcode(LLVMValueRef Src, LLVMBool SrcIsSigned, + LLVMTypeRef DestTy, LLVMBool DestIsSigned) { + return map_to_llvmopcode(CastInst::getCastOpcode( + unwrap(Src), SrcIsSigned, unwrap(DestTy), DestIsSigned)); +} + /*--.. Comparisons .........................................................--*/ LLVMValueRef LLVMBuildICmp(LLVMBuilderRef B, LLVMIntPredicate Op, Index: llvm/unittests/IR/InstructionsTest.cpp =================================================================== --- llvm/unittests/IR/InstructionsTest.cpp +++ llvm/unittests/IR/InstructionsTest.cpp @@ -6,10 +6,11 @@ // //===----------------------------------------------------------------------===// -#include "llvm/AsmParser/Parser.h" #include "llvm/IR/Instructions.h" +#include "llvm-c/Core.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Analysis/ValueTracking.h" +#include "llvm/AsmParser/Parser.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" @@ -388,6 +389,67 @@ delete BB; } +TEST(InstructionsTest, CastCAPI) { + LLVMContext C; + + Type *Int8Ty = Type::getInt8Ty(C); + Type *Int32Ty = Type::getInt32Ty(C); + Type *Int64Ty = Type::getInt64Ty(C); + + Type *FloatTy = Type::getFloatTy(C); + Type *DoubleTy = Type::getDoubleTy(C); + + Type *Int8PtrTy = PointerType::get(Int8Ty, 0); + Type *Int32PtrTy = PointerType::get(Int32Ty, 0); + + const Constant *C8 = Constant::getNullValue(Int8Ty); + const Constant *C64 = Constant::getNullValue(Int64Ty); + + EXPECT_EQ(LLVMBitCast, + LLVMGetCastOpcode(wrap(C64), true, wrap(Int64Ty), true)); + EXPECT_EQ(LLVMTrunc, LLVMGetCastOpcode(wrap(C64), true, wrap(Int8Ty), true)); + EXPECT_EQ(LLVMSExt, LLVMGetCastOpcode(wrap(C8), true, wrap(Int64Ty), true)); + EXPECT_EQ(LLVMZExt, LLVMGetCastOpcode(wrap(C8), false, wrap(Int64Ty), true)); + + const Constant *CF32 = Constant::getNullValue(FloatTy); + const Constant *CF64 = Constant::getNullValue(DoubleTy); + + EXPECT_EQ(LLVMFPToUI, + LLVMGetCastOpcode(wrap(CF32), true, wrap(Int8Ty), false)); + EXPECT_EQ(LLVMFPToSI, + LLVMGetCastOpcode(wrap(CF32), true, wrap(Int8Ty), true)); + EXPECT_EQ(LLVMUIToFP, + LLVMGetCastOpcode(wrap(C8), false, wrap(FloatTy), true)); + EXPECT_EQ(LLVMSIToFP, LLVMGetCastOpcode(wrap(C8), true, wrap(FloatTy), true)); + EXPECT_EQ(LLVMFPTrunc, + LLVMGetCastOpcode(wrap(CF64), true, wrap(FloatTy), true)); + EXPECT_EQ(LLVMFPExt, + LLVMGetCastOpcode(wrap(CF32), true, wrap(DoubleTy), true)); + + const Constant *CPtr8 = Constant::getNullValue(Int8PtrTy); + + EXPECT_EQ(LLVMPtrToInt, + LLVMGetCastOpcode(wrap(CPtr8), true, wrap(Int8Ty), true)); + EXPECT_EQ(LLVMIntToPtr, + LLVMGetCastOpcode(wrap(C8), true, wrap(Int8PtrTy), true)); + + Type *V8x8Ty = FixedVectorType::get(Int8Ty, 8); + Type *V8x64Ty = FixedVectorType::get(Int64Ty, 8); + const Constant *CV8 = Constant::getNullValue(V8x8Ty); + const Constant *CV64 = Constant::getNullValue(V8x64Ty); + + EXPECT_EQ(LLVMTrunc, LLVMGetCastOpcode(wrap(CV64), true, wrap(V8x8Ty), true)); + EXPECT_EQ(LLVMSExt, LLVMGetCastOpcode(wrap(CV8), true, wrap(V8x64Ty), true)); + + Type *Int32PtrAS1Ty = PointerType::get(Int32Ty, 1); + Type *V2Int32PtrAS1Ty = FixedVectorType::get(Int32PtrAS1Ty, 2); + Type *V2Int32PtrTy = FixedVectorType::get(Int32PtrTy, 2); + const Constant *CV2ptr32 = Constant::getNullValue(V2Int32PtrTy); + + EXPECT_EQ(LLVMAddrSpaceCast, LLVMGetCastOpcode(wrap(CV2ptr32), true, + wrap(V2Int32PtrAS1Ty), true)); +} + TEST(InstructionsTest, VectorGep) { LLVMContext C;