Skip to content

Commit

Permalink
Merge remote-tracking branch 'llvm/master' into HEAD
Browse files Browse the repository at this point in the history
Change-Id: Ie75271ac7a1b77b013d0addc984e0a6da0cff71c
  • Loading branch information
jayfoad committed May 5, 2020
2 parents d00989c + 9d273c0 commit 8f20270
Show file tree
Hide file tree
Showing 119 changed files with 2,765 additions and 796 deletions.
2 changes: 1 addition & 1 deletion clang/lib/CodeGen/CGOpenMPRuntime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11150,7 +11150,7 @@ static bool getAArch64PBV(QualType QT, ASTContext &C) {
/// as defined by `LS(P)` in 3.2.1 of the AAVFABI.
/// TODO: Add support for references, section 3.2.1, item 1.
static unsigned getAArch64LS(QualType QT, ParamKindTy Kind, ASTContext &C) {
if (getAArch64MTV(QT, Kind) && QT.getCanonicalType()->isPointerType()) {
if (!getAArch64MTV(QT, Kind) && QT.getCanonicalType()->isPointerType()) {
QualType PTy = QT.getCanonicalType()->getPointeeType();
if (getAArch64PBV(PTy, C))
return C.getTypeSize(PTy);
Expand Down
3 changes: 1 addition & 2 deletions clang/lib/CodeGen/CodeGenPGO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1051,8 +1051,7 @@ llvm::MDNode *CodeGenFunction::createProfileWeightsForLoop(const Stmt *Cond,
if (!PGO.haveRegionCounts())
return nullptr;
Optional<uint64_t> CondCount = PGO.getStmtCount(Cond);
assert(CondCount.hasValue() && "missing expected loop condition count");
if (*CondCount == 0)
if (!CondCount || *CondCount == 0)
return nullptr;
return createProfileWeights(LoopCount,
std::max(*CondCount, LoopCount) - LoopCount);
Expand Down
6 changes: 4 additions & 2 deletions clang/test/Lexer/case-insensitive-include-ms.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,17 @@
// RUN: %clang_cc1 -fsyntax-only -fms-compatibility %s -include %s -I %t/Output -verify
// RUN: %clang_cc1 -fsyntax-only -fms-compatibility -fdiagnostics-parseable-fixits %s -include %s -I %t/Output 2>&1 | FileCheck %s

// FIXME: Add a test with repeated backslashes once clang can handle that
// in ms-compat mode on non-Windows hosts.
#include "..\Output\.\case-insensitive-include.h"
#include "..\Output\.\Case-Insensitive-Include.h" // expected-warning {{non-portable path}}
// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:50}:"\"..\\Output\\.\\case-insensitive-include.h\""
#include "..\\Output\.\\Case-Insensitive-Include.h" // expected-warning {{non-portable path}}
// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:52}:"\"..\\\\Output\\.\\\\case-insensitive-include.h\""
#include "..\output\.\case-insensitive-include.h" // expected-warning {{non-portable path}}
// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:50}:"\"..\\Output\\.\\case-insensitive-include.h\""

#include "apath\..\.\case-insensitive-include.h"
#include "apath\..\.\Case-Insensitive-Include.h" // expected-warning {{non-portable path}}
// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:49}:"\"apath\\..\\.\\case-insensitive-include.h\""
#include "apath\\..\\.\\Case-Insensitive-Include.h" // expected-warning {{non-portable path}}
// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:52}:"\"apath\\\\..\\\\.\\\\case-insensitive-include.h\""
#include "APath\..\.\case-insensitive-include.h" // For the sake of efficiency, this case is not diagnosed. :-(
82 changes: 82 additions & 0 deletions clang/test/OpenMP/aarch64_vfabi_NarrowestDataSize.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +neon -fopenmp -x c -emit-llvm %s -o - -femit-all-decls | FileCheck %s
// RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +neon -fopenmp-simd -x c -emit-llvm %s -o - -femit-all-decls | FileCheck %s

// REQUIRES: aarch64-registered-target
// Note: -fopemp and -fopenmp-simd behavior are expected to be the same.

// This test checks the values of Narrowest Data Size (NDS), as defined in
// https://github.com/ARM-software/abi-aa/tree/master/vfabia64
//
// NDS is used to compute the <vlen> token in the name of AdvSIMD
// vector functions when no `simdlen` is specified, with the rule:
//
// if NDS(f) = 1, then VLEN = 16, 8;
// if NDS(f) = 2, then VLEN = 8, 4;
// if NDS(f) = 4, then VLEN = 4, 2;
// if NDS(f) = 8 or NDS(f) = 16, then VLEN = 2.

// NDS(NDS_is_sizeof_char) = 1
#pragma omp declare simd notinbranch
char NDS_is_sizeof_char(short in);
// CHECK-DAG: _ZGVnN16v_NDS_is_sizeof_char
// CHECK-DAG: _ZGVnN8v_NDS_is_sizeof_char
// CHECK-NOT: _ZGV{{.*}}_NDS_is_sizeof_char

// NDS(NDS_is_sizeof_short) = 2
#pragma omp declare simd notinbranch
int NDS_is_sizeof_short(short in);
// CHECK-DAG: _ZGVnN8v_NDS_is_sizeof_short
// CHECK-DAG: _ZGVnN4v_NDS_is_sizeof_short
// CHECK-NOT: _ZGV{{.*}}_NDS_is_sizeof_short

// NDS(NDS_is_sizeof_float_with_linear) = 4, and not 2, because the pointers are
// marked as `linear` and therefore the size of the pointee realizes
// the NDS.
#pragma omp declare simd linear(sin) notinbranch
void NDS_is_sizeof_float_with_linear(double in, float *sin);
// Neon accepts only power of 2 values as <vlen>.
// CHECK-DAG: _ZGVnN4vl4_NDS_is_sizeof_float_with_linear
// CHECK-DAG: _ZGVnN2vl4_NDS_is_sizeof_float_with_linear
// CHECK-NOT: _ZGV{{.*}}_NDS_is_sizeof_float_with_linear

// NDS(NDS_is_size_of_float) = 4
#pragma omp declare simd notinbranch
double NDS_is_size_of_float(float in);
// CHECK-DAG: _ZGVnN4v_NDS_is_size_of_float
// CHECK-DAG: _ZGVnN2v_NDS_is_size_of_float
// CHECK-NOT: _ZGV{{.*}}_NDS_is_size_of_float

// NDS(NDS_is_sizeof_double) = 8
#pragma omp declare simd linear(sin) notinbranch
void NDS_is_sizeof_double(double in, double *sin);
// CHECK-DAG: _ZGVnN2vl8_NDS_is_sizeof_double
// CHECK-NOT: _ZGV{{.*}}_NDS_is_sizeof_double

// NDS(double_complex) = 16
#pragma omp declare simd notinbranch
double _Complex double_complex(double _Complex);
// CHECK-DAG: _ZGVnN2v_double_complex
// CHECK-NOT: _ZGV{{.*}}_double_complex

// NDS(double_complex_linear_char) = 1, becasue `x` is marked linear.
#pragma omp declare simd linear(x) notinbranch
double _Complex double_complex_linear_char(double _Complex y, char *x);
// CHECK-DAG: _ZGVnN8vl_double_complex_linear_char
// CHECK-DAG: _ZGVnN16vl_double_complex_linear_char
// CHECK-NOT: _ZGV{{.*}}_double_complex_linear_char

static float *F;
static double *D;
static short S;
static int I;
static char C;
static double _Complex DC;
void do_something() {
C = NDS_is_sizeof_char(S);
I = NDS_is_sizeof_short(S);
NDS_is_sizeof_float_with_linear(*D, F);
*D = NDS_is_size_of_float(*F);
NDS_is_sizeof_double(*D, D);
DC = double_complex(DC);
DC = double_complex_linear_char(DC, &C);
}
78 changes: 78 additions & 0 deletions clang/test/OpenMP/aarch64_vfabi_WidestDataSize.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +sve -fopenmp -x c -emit-llvm %s -o - -femit-all-decls | FileCheck %s
// RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +sve -fopenmp-simd -x c -emit-llvm %s -o - -femit-all-decls | FileCheck %s

// REQUIRES: aarch64-registered-target
// Note: -fopemp and -fopenmp-simd behavior are expected to be the same.

// This test checks the values of Widest Data Size (WDS), as defined
// in https://github.com/ARM-software/abi-aa/tree/master/vfabia64
//
// WDS is used to check the accepted values <N> of `simdlen(<N>)` when
// targeting fixed-length SVE vector function names. The values of
// `<N>` that are accepted are such that for X = WDS * <N> * 8,
// 128-bit <= X <= 2048-bit and X is a multiple of 128-bit.

#pragma omp declare simd simdlen(8)
#pragma omp declare simd simdlen(16)
#pragma omp declare simd simdlen(256)
#pragma omp declare simd simdlen(272)
char WDS_is_sizeof_char(char in);
// WDS = 1, simdlen(8) and simdlen(272) are not generated.
// CHECK-DAG: _ZGVsM16v_WDS_is_sizeof_char
// CHECK-DAG: _ZGVsM256v_WDS_is_sizeof_char
// CHECK-NOT: _ZGV{{.*}}_WDS_is_sizeof_char

#pragma omp declare simd simdlen(4)
#pragma omp declare simd simdlen(8)
#pragma omp declare simd simdlen(128)
#pragma omp declare simd simdlen(136)
char WDS_is_sizeof_short(short in);
// WDS = 2, simdlen(4) and simdlen(136) are not generated.
// CHECK-DAG: _ZGVsM8v_WDS_is_sizeof_short
// CHECK-DAG: _ZGVsM128v_WDS_is_sizeof_short
// CHECK-NOT: _ZGV{{.*}}_WDS_is_sizeof_short

#pragma omp declare simd linear(sin) notinbranch simdlen(2)
#pragma omp declare simd linear(sin) notinbranch simdlen(4)
#pragma omp declare simd linear(sin) notinbranch simdlen(64)
#pragma omp declare simd linear(sin) notinbranch simdlen(68)
void WDS_is_sizeof_float_pointee(float in, float *sin);
// WDS = 4, simdlen(2) and simdlen(68) are not generated.
// CHECK-DAG: _ZGVsM4vl4_WDS_is_sizeof_float_pointee
// CHECK-DAG: _ZGVsM64vl4_WDS_is_sizeof_float_pointee
// CHECK-NOT: _ZGV{{.*}}_WDS_is_sizeof_float_pointee

#pragma omp declare simd linear(sin) notinbranch simdlen(2)
#pragma omp declare simd linear(sin) notinbranch simdlen(4)
#pragma omp declare simd linear(sin) notinbranch simdlen(32)
#pragma omp declare simd linear(sin) notinbranch simdlen(34)
void WDS_is_sizeof_double_pointee(float in, double *sin);
// WDS = 8 because of the linear clause, simdlen(34) is not generated.
// CHECK-DAG: _ZGVsM2vl8_WDS_is_sizeof_double_pointee
// CHECK-DAG: _ZGVsM4vl8_WDS_is_sizeof_double_pointee
// CHECK-DAG: _ZGVsM32vl8_WDS_is_sizeof_double_pointee
// CHECK-NOT: _ZGV{{.*}}_WDS_is_sizeof_double_pointee

#pragma omp declare simd simdlen(2)
#pragma omp declare simd simdlen(4)
#pragma omp declare simd simdlen(32)
#pragma omp declare simd simdlen(34)
double WDS_is_sizeof_double(double in);
// WDS = 8, simdlen(34) is not generated.
// CHECK-DAG: _ZGVsM2v_WDS_is_sizeof_double
// CHECK-DAG: _ZGVsM4v_WDS_is_sizeof_double
// CHECK-DAG: _ZGVsM32v_WDS_is_sizeof_double
// CHECK-NOT: _ZGV{{.*}}_WDS_is_sizeof_double

static char C;
static short S;
static float F;
static double D;

void do_something() {
C = WDS_is_sizeof_char(C);
C = WDS_is_sizeof_short(S);
WDS_is_sizeof_float_pointee(F, &F);
WDS_is_sizeof_double_pointee(F, &D);
D = WDS_is_sizeof_double(D);
}
31 changes: 23 additions & 8 deletions flang/include/flang/Evaluate/check-expression.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#define FORTRAN_EVALUATE_CHECK_EXPRESSION_H_

#include "expression.h"
#include "intrinsics.h"
#include "type.h"
#include <optional>

Expand Down Expand Up @@ -41,24 +42,38 @@ bool IsInitialDataTarget(
// Check whether an expression is a specification expression
// (10.1.11(2), C1010). Constant expressions are always valid
// specification expressions.

// There are two contexts where specification expressions appear -- array
// bounds and type param expressions. We need to differentiate them because
// additional checks are required for array bounds expressions in declarations
// of derived type components (see C750).
ENUM_CLASS(SpecificationExprContext, TYPE_PARAM, BOUND)

template <typename A>
void CheckSpecificationExpr(
const A &, parser::ContextualMessages &, const semantics::Scope &);
void CheckSpecificationExpr(const A &, parser::ContextualMessages &,
const semantics::Scope &, const IntrinsicProcTable &,
SpecificationExprContext);
extern template void CheckSpecificationExpr(const Expr<SomeType> &x,
parser::ContextualMessages &, const semantics::Scope &);
parser::ContextualMessages &, const semantics::Scope &,
const IntrinsicProcTable &, SpecificationExprContext);
extern template void CheckSpecificationExpr(const Expr<SomeInteger> &x,
parser::ContextualMessages &, const semantics::Scope &);
parser::ContextualMessages &, const semantics::Scope &,
const IntrinsicProcTable &, SpecificationExprContext);
extern template void CheckSpecificationExpr(const Expr<SubscriptInteger> &x,
parser::ContextualMessages &, const semantics::Scope &);
parser::ContextualMessages &, const semantics::Scope &,
const IntrinsicProcTable &, SpecificationExprContext);
extern template void CheckSpecificationExpr(
const std::optional<Expr<SomeType>> &x, parser::ContextualMessages &,
const semantics::Scope &);
const semantics::Scope &, const IntrinsicProcTable &,
SpecificationExprContext);
extern template void CheckSpecificationExpr(
const std::optional<Expr<SomeInteger>> &x, parser::ContextualMessages &,
const semantics::Scope &);
const semantics::Scope &, const IntrinsicProcTable &,
SpecificationExprContext);
extern template void CheckSpecificationExpr(
const std::optional<Expr<SubscriptInteger>> &x,
parser::ContextualMessages &, const semantics::Scope &);
parser::ContextualMessages &, const semantics::Scope &,
const IntrinsicProcTable &, SpecificationExprContext);

// Simple contiguity (9.5.4)
template <typename A>
Expand Down
8 changes: 8 additions & 0 deletions flang/include/flang/Evaluate/intrinsics.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ struct SpecificIntrinsicFunctionInterface : public characteristics::Procedure {
// All argument and result types are intrinsic types with default kinds.
};

// Generic intrinsic classes from table 16.1
ENUM_CLASS(IntrinsicClass, atomicSubroutine, collectiveSubroutine,
elementalFunction, elementalSubroutine, inquiryFunction, pureSubroutine,
impureSubroutine, transformationalFunction, noClass)

class IntrinsicProcTable {
private:
class Implementation;
Expand All @@ -68,6 +73,9 @@ class IntrinsicProcTable {
// statement.
bool IsIntrinsic(const std::string &) const;

// Inquiry intrinsics are defined in section 16.7, table 16.1
IntrinsicClass GetIntrinsicClass(const std::string &) const;

// Probe the intrinsics for a match against a specific call.
// On success, the actual arguments are transferred to the result
// in dummy argument order; on failure, the actual arguments remain
Expand Down
Loading

0 comments on commit 8f20270

Please sign in to comment.