| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| //===- CIRAttrs.cpp - MLIR CIR Attributes ---------------------------------===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // This file defines the attributes in the CIR dialect. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #include "clang/CIR/Dialect/IR/CIRDialect.h" | ||
|
|
||
| using namespace mlir; | ||
| using namespace mlir::cir; | ||
|
|
||
| //===----------------------------------------------------------------------===// | ||
| // General CIR parsing / printing | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| Attribute CIRDialect::parseAttribute(DialectAsmParser &parser, | ||
| Type type) const { | ||
| // No attributes yet to parse | ||
| return Attribute{}; | ||
| } | ||
|
|
||
| void CIRDialect::printAttribute(Attribute attr, DialectAsmPrinter &os) const { | ||
| // No attributes yet to print | ||
| } | ||
|
|
||
| //===----------------------------------------------------------------------===// | ||
| // CIR Dialect | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| void CIRDialect::registerAttributes() { | ||
| // No attributes yet to register | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| //===- CIRTypes.cpp - MLIR CIR Types --------------------------------------===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // This file defines the types in the CIR dialect. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #include "clang/CIR/Dialect/IR/CIRDialect.h" | ||
|
|
||
| using namespace mlir; | ||
| using namespace mlir::cir; | ||
|
|
||
| //===----------------------------------------------------------------------===// | ||
| // General CIR parsing / printing | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| Type CIRDialect::parseType(DialectAsmParser &parser) const { | ||
| // No types yet to parse | ||
| return Type{}; | ||
| } | ||
|
|
||
| void CIRDialect::printType(Type type, DialectAsmPrinter &os) const { | ||
| // No types yet to print | ||
| } | ||
|
|
||
| //===----------------------------------------------------------------------===// | ||
| // CIR Dialect | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| void CIRDialect::registerTypes() { | ||
| // No types yet to register | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,8 @@ | ||
| add_clang_library(MLIRCIR | ||
| CIRAttrs.cpp | ||
| CIRDialect.cpp | ||
| CIRTypes.cpp | ||
|
|
||
| LINK_LIBS PUBLIC | ||
| MLIRIR | ||
| ) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,5 @@ | ||
| // Smoke test for ClangIR code generation | ||
| // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o - | FileCheck %s | ||
|
|
||
| void foo() {} | ||
| // CHECK: cir.func @foo |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --check-globals all --version 5 | ||
| // RUN: %clang_cc1 "-triple" "nvptx64-nvidia-cuda" -emit-llvm -fcuda-is-device -o - %s | FileCheck %s | ||
|
|
||
| #include "Inputs/cuda.h" | ||
|
|
||
| struct S {}; | ||
|
|
||
| __global__ void kernel(__grid_constant__ const S gc_arg1, int arg2, __grid_constant__ const int gc_arg3) {} | ||
|
|
||
| // dependent arguments get diagnosed after instantiation. | ||
| template <typename T> | ||
| __global__ void tkernel_const(__grid_constant__ const T arg) {} | ||
|
|
||
| template <typename T> | ||
| __global__ void tkernel(int dummy, __grid_constant__ T arg) {} | ||
|
|
||
| void foo() { | ||
| tkernel_const<const S><<<1,1>>>({}); | ||
| tkernel_const<S><<<1,1>>>({}); | ||
| tkernel<const S><<<1,1>>>(1, {}); | ||
| } | ||
| //. | ||
| //. | ||
| // CHECK: [[META0:![0-9]+]] = !{ptr @_Z6kernel1Sii, !"kernel", i32 1, !"grid_constant", [[META1:![0-9]+]]} | ||
| // CHECK: [[META1]] = !{i32 1, i32 3} | ||
| // CHECK: [[META2:![0-9]+]] = !{ptr @_Z13tkernel_constIK1SEvT_, !"kernel", i32 1, !"grid_constant", [[META3:![0-9]+]]} | ||
| // CHECK: [[META3]] = !{i32 1} | ||
| // CHECK: [[META4:![0-9]+]] = !{ptr @_Z13tkernel_constI1SEvT_, !"kernel", i32 1, !"grid_constant", [[META3]]} | ||
| // CHECK: [[META5:![0-9]+]] = !{ptr @_Z7tkernelIK1SEviT_, !"kernel", i32 1, !"grid_constant", [[META6:![0-9]+]]} | ||
| // CHECK: [[META6]] = !{i32 2} | ||
| //. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| // RUN: %clang_cc1 -finclude-default-header -triple \ | ||
| // RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -disable-llvm-passes -o - | \ | ||
| // RUN: FileCheck %s -DTARGET=dx | ||
| // RUN: %clang_cc1 -finclude-default-header -triple \ | ||
| // RUN: spirv-pc-vulkan-compute %s -emit-llvm -disable-llvm-passes -o - | \ | ||
| // RUN: FileCheck %s -DTARGET=spv | ||
|
|
||
| // Test basic lowering to runtime function call. | ||
|
|
||
| // CHECK-LABEL: test | ||
| int test(uint a, uint b, int c) { | ||
| // CHECK: %[[RET:.*]] = call [[TY:i32]] @llvm.[[TARGET]].dot4add.i8packed([[TY]] %[[#]], [[TY]] %[[#]], [[TY]] %[[#]]) | ||
| // CHECK: ret [[TY]] %[[RET]] | ||
| return dot4add_i8packed(a, b, c); | ||
| } | ||
|
|
||
| // CHECK: declare [[TY]] @llvm.[[TARGET]].dot4add.i8packed([[TY]], [[TY]], [[TY]]) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| // RUN: %clang_cc1 -fsyntax-only -verify %s | ||
| // RUN: %clang_cc1 -fsyntax-only -fcuda-is-device -verify %s | ||
| #include "Inputs/cuda.h" | ||
|
|
||
| struct S {}; | ||
|
|
||
| __global__ void kernel_struct(__grid_constant__ const S arg) {} | ||
| __global__ void kernel_scalar(__grid_constant__ const int arg) {} | ||
|
|
||
| __global__ void gc_kernel_non_const(__grid_constant__ S arg) {} // expected-error {{__grid_constant__ is only allowed on const-qualified kernel parameters}} | ||
|
|
||
| void non_kernel(__grid_constant__ S arg) {} // expected-error {{__grid_constant__ is only allowed on const-qualified kernel parameters}} | ||
|
|
||
| // templates w/ non-dependent argument types get diagnosed right | ||
| // away, without instantiation. | ||
| template <typename T> | ||
| __global__ void tkernel_nd_const(__grid_constant__ const S arg, T dummy) {} | ||
| template <typename T> | ||
| __global__ void tkernel_nd_non_const(__grid_constant__ S arg, T dummy) {} // expected-error {{__grid_constant__ is only allowed on const-qualified kernel parameters}} | ||
|
|
||
| // dependent arguments get diagnosed after instantiation. | ||
| template <typename T> | ||
| __global__ void tkernel_const(__grid_constant__ const T arg) {} | ||
|
|
||
| template <typename T> | ||
| __global__ void tkernel(__grid_constant__ T arg) {} // expected-error {{__grid_constant__ is only allowed on const-qualified kernel parameters}} | ||
|
|
||
| void foo() { | ||
| tkernel_const<const S><<<1,1>>>({}); | ||
| tkernel_const<S><<<1,1>>>({}); | ||
| tkernel<const S><<<1,1>>>({}); | ||
| tkernel<S><<<1,1>>>({}); // expected-note {{in instantiation of function template specialization 'tkernel<S>' requested here}} | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| // RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -emit-llvm-only -disable-llvm-passes -verify | ||
|
|
||
| int test_too_few_arg0() { | ||
| return __builtin_hlsl_dot4add_i8packed(); | ||
| // expected-error@-1 {{too few arguments to function call, expected 3, have 0}} | ||
| } | ||
|
|
||
| int test_too_few_arg1(int p0) { | ||
| return __builtin_hlsl_dot4add_i8packed(p0); | ||
| // expected-error@-1 {{too few arguments to function call, expected 3, have 1}} | ||
| } | ||
|
|
||
| int test_too_few_arg2(int p0) { | ||
| return __builtin_hlsl_dot4add_i8packed(p0, p0); | ||
| // expected-error@-1 {{too few arguments to function call, expected 3, have 2}} | ||
| } | ||
|
|
||
| int test_too_many_arg(int p0) { | ||
| return __builtin_hlsl_dot4add_i8packed(p0, p0, p0, p0); | ||
| // expected-error@-1 {{too many arguments to function call, expected 3, have 4}} | ||
| } | ||
|
|
||
| struct S { float f; }; | ||
|
|
||
| int test_expr_struct_type_check(S p0, int p1) { | ||
| return __builtin_hlsl_dot4add_i8packed(p0, p1, p1); | ||
| // expected-error@-1 {{no viable conversion from 'S' to 'unsigned int'}} | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,109 @@ | ||
| // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.6-library -finclude-default-header -fnative-half-type -verify %s | ||
| // expected-no-diagnostics | ||
|
|
||
| struct oneInt { | ||
| int i; | ||
| }; | ||
|
|
||
| struct twoInt { | ||
| int aa; | ||
| int ab; | ||
| }; | ||
|
|
||
| struct threeInts { | ||
| oneInt o; | ||
| twoInt t; | ||
| }; | ||
|
|
||
| struct oneFloat { | ||
| float f; | ||
| }; | ||
| struct depthDiff { | ||
| int i; | ||
| oneInt o; | ||
| oneFloat f; | ||
| }; | ||
|
|
||
| struct notHomogenous{ | ||
| int i; | ||
| float f; | ||
| }; | ||
|
|
||
| struct EightElements { | ||
| twoInt x[2]; | ||
| twoInt y[2]; | ||
| }; | ||
|
|
||
| struct EightHalves { | ||
| half x[8]; | ||
| }; | ||
|
|
||
| struct intVec { | ||
| int2 i; | ||
| }; | ||
|
|
||
| struct oneIntWithVec { | ||
| int i; | ||
| oneInt i2; | ||
| int2 i3; | ||
| }; | ||
|
|
||
| struct weirdStruct { | ||
| int i; | ||
| intVec iv; | ||
| }; | ||
|
|
||
| _Static_assert(__builtin_hlsl_is_typed_resource_element_compatible(int), ""); | ||
| _Static_assert(__builtin_hlsl_is_typed_resource_element_compatible(float), ""); | ||
| _Static_assert(__builtin_hlsl_is_typed_resource_element_compatible(float4), ""); | ||
| _Static_assert(__builtin_hlsl_is_typed_resource_element_compatible(double2), ""); | ||
| _Static_assert(__builtin_hlsl_is_typed_resource_element_compatible(oneInt), ""); | ||
| _Static_assert(__builtin_hlsl_is_typed_resource_element_compatible(oneFloat), ""); | ||
| _Static_assert(__builtin_hlsl_is_typed_resource_element_compatible(twoInt), ""); | ||
| _Static_assert(__builtin_hlsl_is_typed_resource_element_compatible(threeInts), ""); | ||
| _Static_assert(!__builtin_hlsl_is_typed_resource_element_compatible(notHomogenous), ""); | ||
| _Static_assert(!__builtin_hlsl_is_typed_resource_element_compatible(depthDiff), ""); | ||
| _Static_assert(!__builtin_hlsl_is_typed_resource_element_compatible(EightElements), ""); | ||
| _Static_assert(!__builtin_hlsl_is_typed_resource_element_compatible(EightHalves), ""); | ||
| _Static_assert(__builtin_hlsl_is_typed_resource_element_compatible(oneIntWithVec), ""); | ||
| _Static_assert(__builtin_hlsl_is_typed_resource_element_compatible(weirdStruct), ""); | ||
| _Static_assert(!__builtin_hlsl_is_typed_resource_element_compatible(RWBuffer<int>), ""); | ||
|
|
||
|
|
||
| // arrays not allowed | ||
| _Static_assert(!__builtin_hlsl_is_typed_resource_element_compatible(half[4]), ""); | ||
|
|
||
| template<typename T> struct TemplatedBuffer { | ||
| T a; | ||
| __hlsl_resource_t h; | ||
| }; | ||
| _Static_assert(!__builtin_hlsl_is_typed_resource_element_compatible(TemplatedBuffer<int>), ""); | ||
|
|
||
| struct MyStruct1 : TemplatedBuffer<float> { | ||
| float x; | ||
| }; | ||
| _Static_assert(!__builtin_hlsl_is_typed_resource_element_compatible(MyStruct1), ""); | ||
|
|
||
| struct MyStruct2 { | ||
| const TemplatedBuffer<float> TB[10]; | ||
| }; | ||
| _Static_assert(!__builtin_hlsl_is_typed_resource_element_compatible(MyStruct2), ""); | ||
|
|
||
| template<typename T> struct SimpleTemplate { | ||
| T a; | ||
| }; | ||
|
|
||
| // though the element type is incomplete, the type trait should still technically return true | ||
| _Static_assert(__builtin_hlsl_is_typed_resource_element_compatible(SimpleTemplate<__hlsl_resource_t>), ""); | ||
|
|
||
| _Static_assert(__builtin_hlsl_is_typed_resource_element_compatible(SimpleTemplate<float>), ""); | ||
|
|
||
|
|
||
| typedef int myInt; | ||
|
|
||
| struct TypeDefTest { | ||
| int x; | ||
| myInt y; | ||
| }; | ||
|
|
||
| _Static_assert(__builtin_hlsl_is_typed_resource_element_compatible(TypeDefTest), ""); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.6-library -finclude-default-header -fnative-half-type -verify %s | ||
|
|
||
| // types must be complete | ||
| _Static_assert(__builtin_hlsl_is_typed_resource_element_compatible(__hlsl_resource_t), ""); | ||
|
|
||
| // expected-note@+1{{forward declaration of 'notComplete'}} | ||
| struct notComplete; | ||
| // expected-error@+1{{incomplete type 'notComplete' where a complete type is required}} | ||
| _Static_assert(!__builtin_hlsl_is_typed_resource_element_compatible(notComplete), ""); | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -14,6 +14,7 @@ | |
|
|
||
| #include "FuzzerExtFunctions.h" | ||
| #include "FuzzerIO.h" | ||
| #include <stdlib.h> | ||
|
|
||
| using namespace fuzzer; | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,88 @@ | ||
| //===-- xray_s390x.cpp ------------------------------------------*- C++ -*-===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // This file is a part of XRay, a dynamic runtime instrumentation system. | ||
| // | ||
| // Implementation of s390x routines. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| #include "sanitizer_common/sanitizer_common.h" | ||
| #include "xray_defs.h" | ||
| #include "xray_interface_internal.h" | ||
| #include <cassert> | ||
| #include <cstring> | ||
|
|
||
| bool __xray::patchFunctionEntry(const bool Enable, uint32_t FuncId, | ||
| const XRaySledEntry &Sled, | ||
| void (*Trampoline)()) XRAY_NEVER_INSTRUMENT { | ||
| uint32_t *Address = reinterpret_cast<uint32_t *>(Sled.address()); | ||
| if (Enable) { | ||
| // The resulting code is: | ||
| // stmg %r2, %r15, 16(%r15) | ||
| // llilf %2, FuncID | ||
| // brasl %r14, __xray_FunctionEntry@GOT | ||
| // The FuncId and the stmg instruction must be written. | ||
|
|
||
| // Write FuncId into llilf. | ||
| Address[2] = FuncId; | ||
| // Write last part of stmg. | ||
| reinterpret_cast<uint16_t *>(Address)[2] = 0x24; | ||
| // Write first part of stmg. | ||
| Address[0] = 0xeb2ff010; | ||
| } else { | ||
| // j +16 instructions. | ||
| Address[0] = 0xa7f4000b; | ||
| } | ||
| return true; | ||
| } | ||
|
|
||
| bool __xray::patchFunctionExit(const bool Enable, uint32_t FuncId, | ||
| const XRaySledEntry &Sled) | ||
| XRAY_NEVER_INSTRUMENT { | ||
| uint32_t *Address = reinterpret_cast<uint32_t *>(Sled.address()); | ||
| if (Enable) { | ||
| // The resulting code is: | ||
| // stmg %r2, %r15, 24(%r15) | ||
| // llilf %2,FuncID | ||
| // j __xray_FunctionEntry@GOT | ||
| // The FuncId and the stmg instruction must be written. | ||
|
|
||
| // Write FuncId into llilf. | ||
| Address[2] = FuncId; | ||
| // Write last part of of stmg. | ||
| reinterpret_cast<uint16_t *>(Address)[2] = 0x24; | ||
| // Write first part of stmg. | ||
| Address[0] = 0xeb2ff010; | ||
| } else { | ||
| // br %14 instruction. | ||
| reinterpret_cast<uint16_t *>(Address)[0] = 0x07fe; | ||
| } | ||
| return true; | ||
| } | ||
|
|
||
| bool __xray::patchFunctionTailExit(const bool Enable, const uint32_t FuncId, | ||
| const XRaySledEntry &Sled) | ||
| XRAY_NEVER_INSTRUMENT { | ||
| return patchFunctionExit(Enable, FuncId, Sled); | ||
| } | ||
|
|
||
| bool __xray::patchCustomEvent(const bool Enable, const uint32_t FuncId, | ||
| const XRaySledEntry &Sled) XRAY_NEVER_INSTRUMENT { | ||
| // TODO Implement. | ||
| return false; | ||
| } | ||
|
|
||
| bool __xray::patchTypedEvent(const bool Enable, const uint32_t FuncId, | ||
| const XRaySledEntry &Sled) XRAY_NEVER_INSTRUMENT { | ||
| // TODO Implement. | ||
| return false; | ||
| } | ||
|
|
||
| extern "C" void __xray_ArgLoggerEntry() XRAY_NEVER_INSTRUMENT { | ||
| // TODO this will have to be implemented in the trampoline assembly file. | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,176 @@ | ||
| //===-- xray_trampoline_s390x.s ---------------------------------*- ASM -*-===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // This file is a part of XRay, a dynamic runtime instrumentation system. | ||
| // | ||
| // This implements the s390x-specific assembler for the trampolines. | ||
| // 2 versions of the functions are provided: one which does not store the | ||
| // vector registers, and one which does store them. The compiler decides | ||
| // which to call based on the availability of the vector extension. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| .text | ||
|
|
||
| // Minimal stack frame size | ||
| #define STACKSZ 160 | ||
|
|
||
| // Minimal stack frame size (160) plus space for 8 vector registers a 16 bytes. | ||
| #define STACKSZ_VEC 288 | ||
|
|
||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| .globl __xray_FunctionEntry | ||
| .p2align 4 | ||
| .type __xray_FunctionEntry,@function | ||
| __xray_FunctionEntry: | ||
| # The registers r2-15 of the instrumented function are already saved in the | ||
| # stack frame. On entry, r2 contains the function id, and %r14 the address | ||
| # of the first instruction of the instrumented function. | ||
| # Register r14 will be stored in the slot reserved for compiler use. | ||
| stg %r14, 8(%r15) | ||
| std %f0, 128(%r15) | ||
| std %f2, 136(%r15) | ||
| std %f4, 144(%r15) | ||
| std %f6, 152(%r15) | ||
| aghi %r15, -STACKSZ | ||
|
|
||
| lgrl %r1, _ZN6__xray19XRayPatchedFunctionE@GOT | ||
| ltg %r1, 0(%r1) | ||
| je .Lrestore0 | ||
|
|
||
| # Set r3 to XRayEntryType::ENTRY = 0. | ||
| # The FuncId is still stored in r2. | ||
| lghi %r3, 0 | ||
| basr %r14, %r1 | ||
|
|
||
| .Lrestore0: | ||
| ld %f6, STACKSZ+152(%r15) | ||
| ld %f4, STACKSZ+144(%r15) | ||
| ld %f2, STACKSZ+136(%r15) | ||
| ld %f0, STACKSZ+128(%r15) | ||
| lmg %r1, %r15, STACKSZ+8(%r15) | ||
| br %r1 | ||
| .Lfunc_end0: | ||
| .size __xray_FunctionEntry, .Lfunc_end0-__xray_FunctionEntry | ||
|
|
||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| .globl __xray_FunctionEntryVec | ||
| .p2align 4 | ||
| .type __xray_FunctionEntryVec,@function | ||
| __xray_FunctionEntryVec: | ||
| # The registers r2-15 of the instrumented function are already saved in the | ||
| # stack frame. On entry, r2 contains the function id, and %r14 the address | ||
| # of the first instruction of the instrumented function. | ||
| # Register r14 will be stored in the slot reserved for compiler use. | ||
| stg %r14, 8(%r15) | ||
| std %f0, 128(%r15) | ||
| std %f2, 136(%r15) | ||
| std %f4, 144(%r15) | ||
| std %f6, 152(%r15) | ||
| aghi %r15, -STACKSZ_VEC | ||
| vstm %v24, %v31, 160(%r15) | ||
|
|
||
| lgrl %r1, _ZN6__xray19XRayPatchedFunctionE@GOT | ||
| ltg %r1, 0(%r1) | ||
| je .Lrestore1 | ||
|
|
||
| # Set r3 to XRayEntryType::ENTRY = 0. | ||
| # The FuncId is still stored in r2. | ||
| lghi %r3, 0 | ||
| basr %r14, %r1 | ||
|
|
||
| .Lrestore1: | ||
| vlm %v24, %v31, 160(%r15) | ||
| ld %f6, STACKSZ_VEC+152(%r15) | ||
| ld %f4, STACKSZ_VEC+144(%r15) | ||
| ld %f2, STACKSZ_VEC+136(%r15) | ||
| ld %f0, STACKSZ_VEC+128(%r15) | ||
| lmg %r1, %r15, STACKSZ_VEC+8(%r15) | ||
| br %r1 | ||
| .Lfunc_end1: | ||
| .size __xray_FunctionEntryVec, .Lfunc_end1-__xray_FunctionEntryVec | ||
|
|
||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| .globl __xray_FunctionExit | ||
| .p2align 4 | ||
| .type __xray_FunctionExit,@function | ||
| __xray_FunctionExit: | ||
| # The registers r2-15 of the instrumented function are already saved in the | ||
| # stack frame. On entry, the register r2 contains the function id. | ||
| # At the end, the function jumps to the address saved in the slot for r14, | ||
| # which contains the return address into the caller of the instrumented | ||
| # function. | ||
| std %f0, 128(%r15) | ||
| std %f2, 136(%r15) | ||
| std %f4, 144(%r15) | ||
| std %f6, 152(%r15) | ||
| aghi %r15, -STACKSZ | ||
|
|
||
| lgrl %r1, _ZN6__xray19XRayPatchedFunctionE@GOT | ||
| ltg %r1, 0(%r1) | ||
| je .Lrestore2 | ||
|
|
||
| # Set r3 to XRayEntryType::EXIT = 1. | ||
| # The FuncId is still stored in r2. | ||
| lghi %r3, 1 | ||
| basr %r14, %r1 | ||
|
|
||
| .Lrestore2: | ||
| ld %f6, STACKSZ+152(%r15) | ||
| ld %f4, STACKSZ+144(%r15) | ||
| ld %f2, STACKSZ+136(%r15) | ||
| ld %f0, STACKSZ+128(%r15) | ||
| lmg %r2, %r15, STACKSZ+16(%r15) | ||
| br %r14 | ||
| .Lfunc_end2: | ||
| .size __xray_FunctionExit, .Lfunc_end2-__xray_FunctionExit | ||
|
|
||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| .globl __xray_FunctionExitVec | ||
| .p2align 4 | ||
| .type __xray_FunctionExitVec,@function | ||
| __xray_FunctionExitVec: | ||
| # The registers r2-15 of the instrumented function are already saved in the | ||
| # stack frame. On entry, the register r2 contains the function id. | ||
| # At the end, the function jumps to the address saved in the slot for r14, | ||
| # which contains the return address into the caller of the instrumented | ||
| # function. | ||
| std %f0, 128(%r15) | ||
| std %f2, 136(%r15) | ||
| std %f4, 144(%r15) | ||
| std %f6, 152(%r15) | ||
| aghi %r15, -STACKSZ_VEC | ||
| vstm %v24, %v31, 160(%r15) | ||
|
|
||
| lgrl %r1, _ZN6__xray19XRayPatchedFunctionE@GOT | ||
| ltg %r1, 0(%r1) | ||
| je .Lrestore3 | ||
|
|
||
| # Set r3 to XRayEntryType::EXIT = 1. | ||
| # The FuncId is still stored in r2. | ||
| lghi %r3, 1 | ||
| basr %r14, %r1 | ||
|
|
||
| .Lrestore3: | ||
| vlm %v24, %v31, 160(%r15) | ||
| ld %f6, STACKSZ_VEC+152(%r15) | ||
| ld %f4, STACKSZ_VEC+144(%r15) | ||
| ld %f2, STACKSZ_VEC+136(%r15) | ||
| ld %f0, STACKSZ_VEC+128(%r15) | ||
| lmg %r2, %r15, STACKSZ_VEC+16(%r15) | ||
| br %r14 | ||
| .Lfunc_end3: | ||
| .size __xray_FunctionExit, .Lfunc_end3-__xray_FunctionExit | ||
|
|
||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| .section ".note.GNU-stack","",@progbits |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,117 @@ | ||
| ! RUN: %flang -E %s 2>&1 | FileCheck %s | ||
|
|
||
| ! CHECK: print *, 'pass 1' | ||
| #define IS_DEFINED | ||
| #define M1 defined(IS_DEFINED) | ||
| #if M1 | ||
| print *, 'pass 1' | ||
| #else | ||
| print *, 'fail 1' | ||
| #endif | ||
|
|
||
| ! CHECK: print *, 'pass 2' | ||
| #define M2 defined IS_DEFINED | ||
| #if M2 | ||
| print *, 'pass 2' | ||
| #else | ||
| print *, 'fail 2' | ||
| #endif | ||
|
|
||
| ! CHECK: print *, 'pass 3' | ||
| #define M3 defined(IS_UNDEFINED) | ||
| #if M3 | ||
| print *, 'fail 3' | ||
| #else | ||
| print *, 'pass 3' | ||
| #endif | ||
|
|
||
| ! CHECK: print *, 'pass 4' | ||
| #define M4 defined IS_UNDEFINED | ||
| #if M4 | ||
| print *, 'fail 4' | ||
| #else | ||
| print *, 'pass 4' | ||
| #endif | ||
|
|
||
| ! CHECK: print *, 'pass 5' | ||
| #define DEFINED_KEYWORD defined | ||
| #define M5(x) DEFINED_KEYWORD(x) | ||
| #define KWM1 1 | ||
| #if M5(KWM1) | ||
| print *, 'pass 5' | ||
| #else | ||
| print *, 'fail 5' | ||
| #endif | ||
|
|
||
| ! CHECK: print *, 'pass 6' | ||
| #define KWM2 KWM1 | ||
| #if M5(KWM2) | ||
| print *, 'pass 6' | ||
| #else | ||
| print *, 'fail 6' | ||
| #endif | ||
|
|
||
| ! CHECK: print *, 'pass 7' | ||
| #if M5(IS_UNDEFINED) | ||
| print *, 'fail 7' | ||
| #else | ||
| print *, 'pass 7' | ||
| #endif | ||
|
|
||
| ! CHECK: print *, 'pass 8' | ||
| #define KWM3 IS_UNDEFINED | ||
| #if M5(KWM3) | ||
| print *, 'pass 8' | ||
| #else | ||
| print *, 'fail 8' | ||
| #endif | ||
|
|
||
| ! CHECK: print *, 'pass 9' | ||
| #define M6(x) defined(x) | ||
| #if M6(KWM1) | ||
| print *, 'pass 9' | ||
| #else | ||
| print *, 'fail 9' | ||
| #endif | ||
|
|
||
| ! CHECK: print *, 'pass 10' | ||
| #if M6(KWM2) | ||
| print *, 'pass 10' | ||
| #else | ||
| print *, 'fail 10' | ||
| #endif | ||
|
|
||
| ! CHECK: print *, 'pass 11' | ||
| #if M6(IS_UNDEFINED) | ||
| print *, 'fail 11' | ||
| #else | ||
| print *, 'pass 11' | ||
| #endif | ||
|
|
||
| ! CHECK: print *, 'pass 12' | ||
| #if M6(KWM3) | ||
| print *, 'pass 12' | ||
| #else | ||
| print *, 'fail 12' | ||
| #endif | ||
|
|
||
| ! CHECK: print *, 'pass 13' | ||
| #define M7(A, B) ((A) * 10000 + (B) * 100) | ||
| #define M8(A, B, C, AA, BB) ( \ | ||
| (defined(AA) && defined(BB)) && \ | ||
| (M7(A, B) C M7(AA, BB))) | ||
| #if M8(9, 5, >, BAZ, FUX) | ||
| print *, 'fail 13' | ||
| #else | ||
| print *, 'pass 13' | ||
| #endif | ||
|
|
||
| ! CHECK: print *, 'pass 14' | ||
| #define M9() (defined(IS_UNDEFINED)) | ||
| #if M9() | ||
| print *, 'fail 14' | ||
| #else | ||
| print *, 'pass 14' | ||
| #endif | ||
|
|
||
| end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| !RUN: %flang_fc1 -fdebug-unparse %s 2>&1 | FileCheck %s | ||
| !Test rewriting of misparsed statement function definitions | ||
| !into array element assignment statements. | ||
|
|
||
| program main | ||
| real sf(1) | ||
| integer :: j = 1 | ||
| !CHECK: sf(int(j,kind=8))=1._4 | ||
| sf(j) = 1. | ||
| end | ||
|
|
||
| function func | ||
| real sf(1) | ||
| integer :: j = 1 | ||
| !CHECK: sf(int(j,kind=8))=2._4 | ||
| sf(j) = 2. | ||
| func = 0. | ||
| end | ||
|
|
||
| subroutine subr | ||
| real sf(1) | ||
| integer :: j = 1 | ||
| !CHECK: sf(int(j,kind=8))=3._4 | ||
| sf(j) = 3. | ||
| end | ||
|
|
||
| module m | ||
| interface | ||
| module subroutine smp | ||
| end | ||
| end interface | ||
| end | ||
| submodule(m) sm | ||
| contains | ||
| module procedure smp | ||
| real sf(1) | ||
| integer :: j = 1 | ||
| !CHECK: sf(int(j,kind=8))=4._4 | ||
| sf(j) = 4. | ||
| end | ||
| end | ||
|
|
||
| subroutine block | ||
| block | ||
| real sf(1) | ||
| integer :: j = 1 | ||
| !CHECK: sf(int(j,kind=8))=5._4 | ||
| sf(j) = 5. | ||
| end block | ||
| end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| // RUN: fir-opt --add-debug-info --mlir-print-debuginfo %s | FileCheck %s | ||
|
|
||
| module attributes {dlti.dl_spec = #dlti.dl_spec<>} { | ||
| func.func @_QFPfn(%arg0: !fir.box<!fir.array<*:i32>> ) { | ||
| %1 = fir.undefined !fir.dscope | ||
| %2 = fircg.ext_declare %arg0 dummy_scope %1 {uniq_name = "_QFFfnEx"} : (!fir.box<!fir.array<*:i32>>, !fir.dscope) -> !fir.box<!fir.array<*:i32>> loc(#loc2) | ||
| return | ||
| } loc(#loc1) | ||
| } | ||
| #loc1 = loc("test1.f90":1:1) | ||
| #loc2 = loc("test1.f90":3:16) | ||
|
|
||
| // CHECK: #[[TY:.*]] = #llvm.di_composite_type<tag = DW_TAG_array_type{{.*}}elements = #llvm.di_generic_subrange<count = #llvm.di_expression<[DW_OP_push_object_address, DW_OP_over, DW_OP_constu(24), DW_OP_mul, DW_OP_plus_uconst(32), DW_OP_plus, DW_OP_deref]>, lowerBound = #llvm.di_expression<[DW_OP_push_object_address, DW_OP_over, DW_OP_constu(24), DW_OP_mul, DW_OP_plus_uconst(24), DW_OP_plus, DW_OP_deref]>, stride = #llvm.di_expression<[DW_OP_push_object_address, DW_OP_over, DW_OP_constu(24), DW_OP_mul, DW_OP_plus_uconst(40), DW_OP_plus, DW_OP_deref]>>, dataLocation = <[DW_OP_push_object_address, DW_OP_deref]>, rank = <[DW_OP_push_object_address, DW_OP_plus_uconst(20), DW_OP_deref_size(1)]>> | ||
| // CHECK: #llvm.di_local_variable<{{.*}}name = "x"{{.*}}type = #[[TY]]{{.*}}> |