From f888e52a1467a0cc68e3b979fae99246d802a486 Mon Sep 17 00:00:00 2001 From: arphaman Date: Thu, 19 Sep 2013 19:03:48 +0100 Subject: added support for FLOOR and CEILING intrinsic --- include/flang/AST/IntrinsicFunctions.def | 5 ++++- include/flang/Basic/LangOptions.h | 2 ++ lib/CodeGen/CGIntrinsic.cpp | 8 +++++++- lib/Parse/Lexer.cpp | 12 ++++++++++-- lib/Sema/SemaIntrinsic.cpp | 8 +++++--- test/CodeGen/scalarIntrinsicTruncRound.f95 | 5 ++++- 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) -- cgit v1.2.1