summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorarphaman <arphaman@gmail.com>2013-09-19 19:03:48 +0100
committerarphaman <arphaman@gmail.com>2013-09-19 19:03:48 +0100
commitf888e52a1467a0cc68e3b979fae99246d802a486 (patch)
treeebd83ec44cdd536c9ed38f0dc938f4c4d50472b5
parentc141d456b204552c6d6b1a2a74a3b04d9fc790a4 (diff)
downloadflang-f888e52a1467a0cc68e3b979fae99246d802a486.tar.gz
added support for FLOOR and CEILING intrinsic
-rw-r--r--include/flang/AST/IntrinsicFunctions.def5
-rw-r--r--include/flang/Basic/LangOptions.h2
-rw-r--r--lib/CodeGen/CGIntrinsic.cpp8
-rw-r--r--lib/Parse/Lexer.cpp12
-rw-r--r--lib/Sema/SemaIntrinsic.cpp8
-rw-r--r--test/CodeGen/scalarIntrinsicTruncRound.f955
-rw-r--r--test/Sema/intrinsicFunctions.f954
7 files changed, 35 insertions, 9 deletions
diff --git a/include/flang/AST/IntrinsicFunctions.def b/include/flang/AST/IntrinsicFunctions.def
index 111545287c..f97008d253 100644
--- a/include/flang/AST/IntrinsicFunctions.def
+++ b/include/flang/AST/IntrinsicFunctions.def
@@ -117,7 +117,10 @@ INTRINSIC_FUNCTION(DNINT, ANINT, NUM_ARGS_1, FUNALL)
INTRINSIC_FUNCTION(NINT, NINT, NUM_ARGS_1, FUNALL)
INTRINSIC_FUNCTION(IDNINT, NINT, NUM_ARGS_1, FUNALL)
-INTRINSIC_GROUP(TRUNCATION, AINT, IDNINT)
+INTRINSIC_FUNCTION(CEILING, CEILING, NUM_ARGS_1, FUNNOTF77)
+INTRINSIC_FUNCTION(FLOOR, FLOOR, NUM_ARGS_1, FUNNOTF77)
+
+INTRINSIC_GROUP(TRUNCATION, AINT, FLOOR)
//
// No group
diff --git a/include/flang/Basic/LangOptions.h b/include/flang/Basic/LangOptions.h
index 29eee9edaa..35bf54f394 100644
--- a/include/flang/Basic/LangOptions.h
+++ b/include/flang/Basic/LangOptions.h
@@ -41,6 +41,7 @@ public:
unsigned DefaultReal8 : 1; // Sets the default real type to be 8 bytes wide
unsigned DefaultDouble8 : 1; // Sets the default double precision type to be 8 bytes wide
unsigned DefaultInt8 : 1; // Sets the default integer type to be 8 bytes wide
+ unsigned TabWidth; // The tab character is treated as N spaces.
LangOptions() {
Fortran77 = 0;
@@ -50,6 +51,7 @@ public:
ReturnComments = 0;
SpellChecking = 1;
DefaultReal8 = DefaultDouble8 = DefaultInt8 = 0;
+ TabWidth = 6;
}
};
diff --git a/lib/CodeGen/CGIntrinsic.cpp b/lib/CodeGen/CGIntrinsic.cpp
index e0f833e25f..cbdb6c043a 100644
--- a/lib/CodeGen/CGIntrinsic.cpp
+++ b/lib/CodeGen/CGIntrinsic.cpp
@@ -136,10 +136,16 @@ llvm::Value *CodeGenFunction::EmitIntrinsicCallScalarTruncation(intrinsic::Funct
case intrinsic::NINT:
FuncDecl = GetIntrinsicFunction(llvm::Intrinsic::rint, ValueType);
break;
+ case intrinsic::CEILING:
+ FuncDecl = GetIntrinsicFunction(llvm::Intrinsic::ceil, ValueType);
+ break;
+ case intrinsic::FLOOR:
+ FuncDecl = GetIntrinsicFunction(llvm::Intrinsic::floor, ValueType);
+ break;
}
auto Result = Builder.CreateCall(FuncDecl, Value);
- if(Func == intrinsic::NINT)
+ if(ResultType->isIntegerType())
return EmitScalarToScalarConversion(Result, ResultType);
return Result;
}
diff --git a/lib/Parse/Lexer.cpp b/lib/Parse/Lexer.cpp
index e2a33272d6..c314ab9989 100644
--- a/lib/Parse/Lexer.cpp
+++ b/lib/Parse/Lexer.cpp
@@ -28,6 +28,7 @@ namespace flang {
static void InitCharacterInfo();
static bool isWhitespace(unsigned char c);
static bool isHorizontalWhitespace(unsigned char c);
+static bool isHorizontalTab(unsigned char c);
static bool isVerticalWhitespace(unsigned char c);
Lexer::Lexer(llvm::SourceMgr &SM, const LangOptions &features, DiagnosticsEngine &D)
@@ -153,8 +154,10 @@ SkipFixedFormBlankLinesAndComments(unsigned &I, const char *&LineBegin) {
while (isVerticalWhitespace(*BufPtr) && *BufPtr != '\0')
++BufPtr;
- while (I != 72 && isHorizontalWhitespace(*BufPtr) && *BufPtr != '\0')
- ++I, ++BufPtr;
+ while (I != 72 && isHorizontalWhitespace(*BufPtr) && *BufPtr != '\0') {
+ I += isHorizontalTab(*BufPtr)? LanguageOptions.TabWidth : 1;
+ ++BufPtr;
+ }
if(I == 0 && (*BufPtr == 'C' || *BufPtr == 'c' || *BufPtr == '*')) {
do {
@@ -627,6 +630,11 @@ static inline bool isHorizontalWhitespace(unsigned char c) {
return (CharInfo[c] & CHAR_HORZ_WS) ? true : false;
}
+/// isHorizontalTab - Return true if this character is horizontal tab.
+static inline bool isHorizontalTab(unsigned char c) {
+ return c == '\t';
+}
+
/// isVerticalWhitespace - Return true if this character is vertical whitespace:
/// '\n', '\r'. Note that this returns false for '\0'.
static inline bool isVerticalWhitespace(unsigned char c) {
diff --git a/lib/Sema/SemaIntrinsic.cpp b/lib/Sema/SemaIntrinsic.cpp
index a856320968..34333661b2 100644
--- a/lib/Sema/SemaIntrinsic.cpp
+++ b/lib/Sema/SemaIntrinsic.cpp
@@ -168,8 +168,8 @@ bool Sema::CheckIntrinsicTruncationFunc(intrinsic::FunctionKind Function,
auto GenericFunction = getGenericFunctionKind(Function);
if(GenericFunction != Function)
- CheckDoublePrecisionRealArgument(Arg);
- else CheckRealArgument(Arg);
+ CheckDoublePrecisionRealArgument(Arg, true);
+ else CheckRealArgument(Arg, true);
switch(GenericFunction) {
case AINT:
@@ -177,7 +177,9 @@ bool Sema::CheckIntrinsicTruncationFunc(intrinsic::FunctionKind Function,
ReturnType = Arg->getType();
break;
case NINT:
- ReturnType = Context.IntegerTy;
+ case CEILING:
+ case FLOOR:
+ ReturnType = GetUnaryReturnType(Arg, Context.IntegerTy);
break;
}
return false;
diff --git a/test/CodeGen/scalarIntrinsicTruncRound.f95 b/test/CodeGen/scalarIntrinsicTruncRound.f95
index f7c787bf2d..0d6702f5c0 100644
--- a/test/CodeGen/scalarIntrinsicTruncRound.f95
+++ b/test/CodeGen/scalarIntrinsicTruncRound.f95
@@ -3,7 +3,7 @@ PROGRAM testscalartruncround
INTEGER i
REAL x
- INTRINSIC aint, anint, nint
+ INTRINSIC aint, anint, nint, ceiling, floor
x = 2.25
@@ -15,4 +15,7 @@ PROGRAM testscalartruncround
CONTINUE ! CHECK: fptosi
CONTINUE ! CHECK: store i32
+ i = ceiling(x) ! CHECK: call float @llvm.ceil.f32
+ i = floor(x) ! CHECK: call float @llvm.floor.f32
+
END PROGRAM
diff --git a/test/Sema/intrinsicFunctions.f95 b/test/Sema/intrinsicFunctions.f95
index 6797aa7065..621dd2391b 100644
--- a/test/Sema/intrinsicFunctions.f95
+++ b/test/Sema/intrinsicFunctions.f95
@@ -17,7 +17,7 @@ PROGRAM intrinfuntest
INTRINSIC DBLE, cmplx
INTRINSIC char, ICHAR
- INTRINSIC AINT, dint, anint, DNINT, nint, IDNINT
+ INTRINSIC AINT, dint, anint, DNINT, nint, IDNINT, ceiling, floor
INTRINSIC abs, iabs, dabs, cabs
INTRINSIC mod, sign, dim, dprod, max, min
INTRINSIC len, len_trim, index
@@ -101,6 +101,8 @@ PROGRAM intrinfuntest
i = IDNINT(d) ! CHECK: i = idnint(d)
i = IDNINT(r) ! expected-error {{passing 'real' to parameter of incompatible type 'double precision'}}
+ i = ceiling(r) + floor(d) ! CHECK: i = (ceiling(r)+floor(d))
+
i = ABS(i) ! CHECK: i = abs(i)
r = ABS(r) ! CHECK: r = abs(r)
d = ABS(d) ! CHECK: d = abs(d)