diff options
author | arphaman <arphaman@gmail.com> | 2013-09-19 19:03:48 +0100 |
---|---|---|
committer | arphaman <arphaman@gmail.com> | 2013-09-19 19:03:48 +0100 |
commit | f888e52a1467a0cc68e3b979fae99246d802a486 (patch) | |
tree | ebd83ec44cdd536c9ed38f0dc938f4c4d50472b5 | |
parent | c141d456b204552c6d6b1a2a74a3b04d9fc790a4 (diff) | |
download | flang-f888e52a1467a0cc68e3b979fae99246d802a486.tar.gz |
added support for FLOOR and CEILING intrinsic
-rw-r--r-- | include/flang/AST/IntrinsicFunctions.def | 5 | ||||
-rw-r--r-- | include/flang/Basic/LangOptions.h | 2 | ||||
-rw-r--r-- | lib/CodeGen/CGIntrinsic.cpp | 8 | ||||
-rw-r--r-- | lib/Parse/Lexer.cpp | 12 | ||||
-rw-r--r-- | lib/Sema/SemaIntrinsic.cpp | 8 | ||||
-rw-r--r-- | test/CodeGen/scalarIntrinsicTruncRound.f95 | 5 | ||||
-rw-r--r-- | test/Sema/intrinsicFunctions.f95 | 4 |
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) |