summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorarphaman <arphaman@gmail.com>2013-09-18 13:53:33 +0100
committerarphaman <arphaman@gmail.com>2013-09-18 13:53:33 +0100
commite69861e1210f97934d0a63a43dbcc3ffc86f75fc (patch)
tree240e6c285e285d100b9db3b1ac3ba3b862996b97
parentb20f00676efb425227c621fb15e03e6b21cc8cfc (diff)
downloadflang-e69861e1210f97934d0a63a43dbcc3ffc86f75fc.tar.gz
added CodeGen for KIND, BIT_SIZE and SELECTED_INT_KIND intrinsics
-rw-r--r--lib/CodeGen/CGIntrinsic.cpp26
-rw-r--r--lib/CodeGen/CodeGenFunction.h3
-rw-r--r--test/CodeGen/Intrinsics/inquiry.f9524
3 files changed, 53 insertions, 0 deletions
diff --git a/lib/CodeGen/CGIntrinsic.cpp b/lib/CodeGen/CGIntrinsic.cpp
index ad24c9fa21..c1a200a7a2 100644
--- a/lib/CodeGen/CGIntrinsic.cpp
+++ b/lib/CodeGen/CGIntrinsic.cpp
@@ -103,6 +103,13 @@ RValueTy CodeGenFunction::EmitIntrinsicCall(const IntrinsicCallExpr *E) {
case GROUP_SYSTEM:
return EmitSystemIntrinsic(Func, Args);
+ case GROUP_INQUIRY: {
+ int64_t Val;
+ if(E->EvaluateAsInt(Val, getContext()))
+ return llvm::ConstantInt::get(ConvertType(E->getType()), Val);
+ return EmitInquiryIntrinsic(Func, Args);
+ }
+
default:
llvm_unreachable("invalid intrinsic");
break;
@@ -502,5 +509,24 @@ RValueTy CodeGenFunction::EmitSystemIntrinsic(intrinsic::FunctionKind Func,
return RValueTy();
}
+llvm::Value *CodeGenFunction::EmitInquiryIntrinsic(intrinsic::FunctionKind Func,
+ ArrayRef<Expr*> Arguments) {
+ using namespace intrinsic;
+
+ switch(Func) {
+ case SELECTED_INT_KIND: {
+ auto Func = CGM.GetRuntimeFunction1("selected_int_kind", CGM.Int32Ty, CGM.Int32Ty);
+ CallArgList Args;
+ Args.add(Builder.CreateSExtOrTrunc(EmitScalarExpr(Arguments[0]), CGM.Int32Ty));
+ return EmitCall(Func.getFunction(), Func.getInfo(), Args).asScalar();
+ }
+ default:
+ llvm_unreachable("invalid intrinsic");
+ break;
+ }
+
+ return nullptr;
+}
+
}
} // end namespace flang
diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h
index c85abdc7b3..785f071bc0 100644
--- a/lib/CodeGen/CodeGenFunction.h
+++ b/lib/CodeGen/CodeGenFunction.h
@@ -384,6 +384,9 @@ public:
RValueTy EmitSystemIntrinsic(intrinsic::FunctionKind Func,
ArrayRef<Expr*> Arguments);
+ llvm::Value *EmitInquiryIntrinsic(intrinsic::FunctionKind Func,
+ ArrayRef<Expr*> Arguments);
+
RValueTy EmitArrayIntrinsic(intrinsic::FunctionKind Func,
ArrayRef<Expr*> Arguments);
diff --git a/test/CodeGen/Intrinsics/inquiry.f95 b/test/CodeGen/Intrinsics/inquiry.f95
new file mode 100644
index 0000000000..1d3e61f709
--- /dev/null
+++ b/test/CodeGen/Intrinsics/inquiry.f95
@@ -0,0 +1,24 @@
+! RUN: %flang -emit-llvm -o - %s | %file_check %s
+
+PROGRAM inquirytest
+
+ integer i
+ integer(8) i64
+ complex(8) c8
+
+ data i / bit_size(23) /
+
+ i = kind(i) ! CHECK: store i32 4
+ i = kind(i64) ! CHECK-NEXT: store i32 8
+ i64 = kind(c8) ! CHECK-NEXT: store i64 8
+
+ i = bit_size(i) ! CHECK-NEXT: store i32 32
+ i = bit_size(i64) ! CHECK-NEXT: store i32 64
+
+ i = selected_int_kind(7) ! CHECK-NEXT: store i32 4
+ i = selected_int_kind(1000) ! CHECK-NEXT: store i32 -1
+
+ i = selected_int_kind(i) ! CHECK: call i32 @libflang_selected_int_kind(i32
+ i64 = selected_int_kind(i64) ! CHECK: call i32 @libflang_selected_int_kind(i32
+
+end