Skip to content

Commit

Permalink
[CAPI] Expose CastInst::getCastOpcode in C API
Browse files Browse the repository at this point in the history
Reviewed By: deadalnix

Differential Revision: https://reviews.llvm.org/D91514
  • Loading branch information
jackoalan committed Apr 30, 2022
1 parent 2e7e097 commit 09325d3
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 0 deletions.
4 changes: 4 additions & 0 deletions llvm/docs/ReleaseNotes.rst
Expand Up @@ -134,6 +134,10 @@ Changes to the OCaml bindings
Changes to the C API
--------------------

* 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
--------------------------

Expand Down
3 changes: 3 additions & 0 deletions llvm/include/llvm-c/Core.h
Expand Up @@ -3978,6 +3978,9 @@ LLVMValueRef LLVMBuildFPCast(LLVMBuilderRef, LLVMValueRef Val,
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,
Expand Down
6 changes: 6 additions & 0 deletions llvm/lib/IR/Core.cpp
Expand Up @@ -3921,6 +3921,12 @@ LLVMValueRef LLVMBuildFPCast(LLVMBuilderRef B, LLVMValueRef Val,
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,
Expand Down
62 changes: 62 additions & 0 deletions llvm/unittests/IR/InstructionsTest.cpp
Expand Up @@ -26,6 +26,7 @@
#include "llvm/IR/NoFolder.h"
#include "llvm/IR/Operator.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm-c/Core.h"
#include "gmock/gmock-matchers.h"
#include "gtest/gtest.h"
#include <memory>
Expand Down Expand Up @@ -391,6 +392,67 @@ TEST(InstructionsTest, CastInst) {
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;

Expand Down

0 comments on commit 09325d3

Please sign in to comment.