| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| // RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown -ast-dump %s \ | ||
| // RUN: | FileCheck -strict-whitespace %s | ||
|
|
||
| struct S { | ||
| struct { | ||
| int i; | ||
| }; | ||
| }; | ||
|
|
||
| int accessInRegularFunction() { | ||
| return S().i; | ||
| // CHECK: FunctionDecl {{.*}} accessInRegularFunction 'int ()' | ||
| // CHECK: | `-ReturnStmt {{.*}} | ||
| // CHECK-NEXT: | `-ExprWithCleanups {{.*}} 'int' | ||
| // CHECK-NEXT: | `-ImplicitCastExpr {{.*}} 'int' <LValueToRValue> | ||
| // CHECK-NEXT: | `-MemberExpr {{.*}} 'int' xvalue .i | ||
| // CHECK-NEXT: | `-MemberExpr {{.*}} 'S::(anonymous struct at {{.*}}) | ||
| // CHECK-NEXT: | `-MaterializeTemporaryExpr {{.*}} 'S' xvalue | ||
| // CHECK-NEXT: | `-CXXTemporaryObjectExpr {{.*}} 'S' 'void () noexcept' zeroing | ||
| } | ||
|
|
||
| // AST should look the same in a function template with an unused template | ||
| // parameter. | ||
| template <class> | ||
| int accessInFunctionTemplate() { | ||
| return S().i; | ||
| // CHECK: FunctionDecl {{.*}} accessInFunctionTemplate 'int ()' | ||
| // CHECK: | `-ReturnStmt {{.*}} | ||
| // CHECK-NEXT: | `-ExprWithCleanups {{.*}} 'int' | ||
| // CHECK-NEXT: | `-ImplicitCastExpr {{.*}} 'int' <LValueToRValue> | ||
| // CHECK-NEXT: | `-MemberExpr {{.*}} 'int' xvalue .i | ||
| // CHECK-NEXT: | `-MemberExpr {{.*}} 'S::(anonymous struct at {{.*}}) | ||
| // CHECK-NEXT: | `-MaterializeTemporaryExpr {{.*}} 'S' xvalue | ||
| // CHECK-NEXT: | `-CXXTemporaryObjectExpr {{.*}} 'S' 'void () noexcept' zeroing | ||
| } | ||
|
|
||
| // AST should look the same in an instantiation of the function template. | ||
| // This is a regression test: The AST used to contain the | ||
| // `MaterializeTemporaryExpr` in the wrong place, causing a `MemberExpr` to have | ||
| // a prvalue base (which is not allowed in C++). | ||
| template int accessInFunctionTemplate<int>(); | ||
| // CHECK: FunctionDecl {{.*}} accessInFunctionTemplate 'int ()' explicit_instantiation_definition | ||
| // CHECK: `-ReturnStmt {{.*}} | ||
| // CHECK-NEXT: `-ExprWithCleanups {{.*}} 'int' | ||
| // CHECK-NEXT: `-ImplicitCastExpr {{.*}} 'int' <LValueToRValue> | ||
| // CHECK-NEXT: `-MemberExpr {{.*}} 'int' xvalue .i | ||
| // CHECK-NEXT: `-MemberExpr {{.*}} 'S::(anonymous struct at {{.*}}) | ||
| // CHECK-NEXT: `-MaterializeTemporaryExpr {{.*}} 'S' xvalue | ||
| // CHECK-NEXT: `-CXXTemporaryObjectExpr {{.*}} 'S' 'void () noexcept' zeroing |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| // RUN: %clang_analyze_cc1 -verify %s -fcxx-exceptions -fexceptions -analyzer-checker=core,alpha.deadcode.UnreachableCode | ||
|
|
||
| // expected-no-diagnostics | ||
|
|
||
| void foo(); | ||
|
|
||
| void fp_90162() { | ||
| try { // no-warning: The TryStmt shouldn't be unreachable. | ||
| foo(); | ||
| } catch (int) { | ||
| foo(); // We assume that catch handlers are reachable. | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| // RUN: %clang_cc1 %s -x c++ -std=c++11 -triple x86_64-pc-linux -fsyntax-only -verify -Wno-c++17-extensions | ||
| // RUN: %clang_cc1 %s -x c++ -std=c++11 -triple x86_64-windows-msvc -fsyntax-only -verify=msvc -Wno-c++17-extensions | ||
| // expected-no-diagnostics | ||
|
|
||
| // Check we return non-zero values for supported attributes as per | ||
| // wg21.link/P2552 | ||
| static_assert(__has_cpp_attribute(assume)); | ||
|
|
||
| // The standard does not prescribe a behavior for [[carries_dependency]] | ||
|
|
||
| static_assert(__has_cpp_attribute(deprecated)); | ||
| static_assert(__has_cpp_attribute(fallthrough)); | ||
| static_assert(__has_cpp_attribute(likely)); | ||
| static_assert(__has_cpp_attribute(unlikely)); | ||
| static_assert(__has_cpp_attribute(maybe_unused)); | ||
| static_assert(__has_cpp_attribute(nodiscard)); | ||
| static_assert(__has_cpp_attribute(noreturn)); | ||
|
|
||
| // We do not support [[no_unique_address]] in MSVC emulation mode | ||
| static_assert(__has_cpp_attribute(no_unique_address)); // msvc-error {{static assertion failed}} |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| ! DEFINE: %{resource_dir} = %S/Inputs/resource_dir | ||
| ! RUN: %flang -print-resource-dir -resource-dir=%{resource_dir}.. \ | ||
| ! RUN: | FileCheck -check-prefix=PRINT-RESOURCE-DIR -DFILE=%{resource_dir} %s | ||
| ! PRINT-RESOURCE-DIR: [[FILE]] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| // Test hlfir.where masked region cleanup lowering (the freemem in the tests). | ||
| // RUN: fir-opt %s --lower-hlfir-ordered-assignments | FileCheck %s | ||
|
|
||
| func.func @loop_cleanup(%mask : !fir.ref<!fir.array<2x!fir.logical<4>>>, %x : !fir.ref<!fir.array<2xf32>>, %y : !fir.ref<!fir.array<2xf32>>) { | ||
| hlfir.where { | ||
| %1 = fir.allocmem !fir.array<10xi32> | ||
| hlfir.yield %mask : !fir.ref<!fir.array<2x!fir.logical<4>>> cleanup { | ||
| fir.freemem %1 : !fir.heap<!fir.array<10xi32>> | ||
| } | ||
| } do { | ||
| hlfir.region_assign { | ||
| %1 = fir.allocmem !fir.array<1xi32> | ||
| %2 = fir.allocmem !fir.array<2xi32> | ||
| hlfir.yield %x : !fir.ref<!fir.array<2xf32>> cleanup { | ||
| fir.freemem %2 : !fir.heap<!fir.array<2xi32>> | ||
| fir.freemem %1 : !fir.heap<!fir.array<1xi32>> | ||
| } | ||
| } to { | ||
| %1 = fir.allocmem !fir.array<3xi32> | ||
| %2 = fir.allocmem !fir.array<4xi32> | ||
| hlfir.yield %y : !fir.ref<!fir.array<2xf32>> cleanup { | ||
| fir.freemem %2 : !fir.heap<!fir.array<4xi32>> | ||
| fir.freemem %1 : !fir.heap<!fir.array<3xi32>> | ||
| } | ||
| } | ||
| } | ||
| return | ||
| } | ||
| // CHECK-LABEL: func.func @loop_cleanup( | ||
| // CHECK: %[[VAL_3:.*]] = fir.allocmem !fir.array<10xi32> | ||
| // CHECK: fir.do_loop | ||
| // CHECK: fir.if | ||
| // CHECK: %[[VAL_11:.*]] = fir.allocmem !fir.array<1xi32> | ||
| // CHECK: %[[VAL_12:.*]] = fir.allocmem !fir.array<2xi32> | ||
| // CHECK: %[[VAL_14:.*]] = fir.allocmem !fir.array<3xi32> | ||
| // CHECK: %[[VAL_15:.*]] = fir.allocmem !fir.array<4xi32> | ||
| // CHECK: hlfir.assign | ||
| // CHECK: fir.freemem %[[VAL_15]] : !fir.heap<!fir.array<4xi32>> | ||
| // CHECK: fir.freemem %[[VAL_14]] : !fir.heap<!fir.array<3xi32>> | ||
| // CHECK: fir.freemem %[[VAL_12]] : !fir.heap<!fir.array<2xi32>> | ||
| // CHECK: fir.freemem %[[VAL_11]] : !fir.heap<!fir.array<1xi32>> | ||
| // CHECK: } | ||
| // CHECK: } | ||
| // CHECK: fir.freemem %[[VAL_3]] : !fir.heap<!fir.array<10xi32>> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| ! Test that scalar expressions are not hoisted from WHERE loops | ||
| ! when they do not appear | ||
| ! RUN: bbc -hlfir -o - -pass-pipeline="builtin.module(lower-hlfir-ordered-assignments)" %s | FileCheck %s | ||
|
|
||
| subroutine do_not_hoist_div(n, mask, a) | ||
| integer :: a(10), n | ||
| logical :: mask(10) | ||
| where(mask) a=1/n | ||
| end subroutine | ||
| ! CHECK-LABEL: func.func @_QPdo_not_hoist_div( | ||
| ! CHECK-NOT: arith.divsi | ||
| ! CHECK: fir.do_loop {{.*}} { | ||
| ! CHECK: fir.if {{.*}} { | ||
| ! CHECK: arith.divsi | ||
| ! CHECK: } | ||
| ! CHECK: } | ||
|
|
||
| subroutine do_not_hoist_optional(n, mask, a) | ||
| integer :: a(10) | ||
| integer, optional :: n | ||
| logical :: mask(10) | ||
| where(mask) a=n | ||
| end subroutine | ||
| ! CHECK-LABEL: func.func @_QPdo_not_hoist_optional( | ||
| ! CHECK: %[[VAL_9:.*]]:2 = hlfir.declare {{.*}}"_QFdo_not_hoist_optionalEn" | ||
| ! CHECK-NOT: fir.load %[[VAL_9]] | ||
| ! CHECK: fir.do_loop {{.*}} { | ||
| ! CHECK: fir.if {{.*}} { | ||
| ! CHECK: %[[VAL_15:.*]] = fir.load %[[VAL_9]]#0 : !fir.ref<i32> | ||
| ! CHECK: } | ||
| ! CHECK: } | ||
|
|
||
| subroutine hoist_function(n, mask, a) | ||
| integer :: a(10, 10) | ||
| integer, optional :: n | ||
| logical :: mask(10, 10) | ||
| forall (i=1:10) | ||
| where(mask(i, :)) a(i,:)=ihoist_me(i) | ||
| end forall | ||
| end subroutine | ||
| ! CHECK-LABEL: func.func @_QPhoist_function( | ||
| ! CHECK: fir.do_loop {{.*}} { | ||
| ! CHECK: fir.call @_QPihoist_me | ||
| ! CHECK: fir.do_loop {{.*}} { | ||
| ! CHECK: fir.if %{{.*}} { | ||
| ! CHECK-NOT: fir.call @_QPihoist_me | ||
| ! CHECK: } | ||
| ! CHECK: } | ||
| ! CHECK: } | ||
| ! CHECK-NOT: fir.call @_QPihoist_me |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,198 @@ | ||
| ! Test lowering of non elemental calls and there inputs inside WHERE | ||
| ! constructs. These must be lowered inside hlfir.exactly_once so that | ||
| ! they are properly hoisted once the loops are materialized and | ||
| ! expression evaluations are scheduled. | ||
| ! RUN: bbc -emit-hlfir -o - %s | FileCheck %s | ||
|
|
||
| subroutine test_where(a, b, c) | ||
| real, dimension(:) :: a, b, c | ||
| interface | ||
| function logical_func1() | ||
| logical :: logical_func1(100) | ||
| end function | ||
| function logical_func2() | ||
| logical :: logical_func2(100) | ||
| end function | ||
| real elemental function elem_func(x) | ||
| real, intent(in) :: x | ||
| end function | ||
| end interface | ||
| where (logical_func1()) | ||
| a = b + real_func(a+b+real_func2()) + elem_func(a) | ||
| elsewhere(logical_func2()) | ||
| a(1:ifoo()) = c | ||
| end where | ||
| end subroutine | ||
| ! CHECK-LABEL: func.func @_QPtest_where( | ||
| ! CHECK: hlfir.where { | ||
| ! CHECK-NOT: hlfir.exactly_once | ||
| ! CHECK: %[[VAL_17:.*]] = fir.call @llvm.stacksave.p0() fastmath<contract> : () -> !fir.ref<i8> | ||
| ! CHECK: %[[VAL_19:.*]] = fir.call @_QPlogical_func1() fastmath<contract> : () -> !fir.array<100x!fir.logical<4>> | ||
| ! CHECK: hlfir.yield %{{.*}} : !hlfir.expr<100x!fir.logical<4>> cleanup { | ||
| ! CHECK: fir.call @llvm.stackrestore.p0(%[[VAL_17]]) fastmath<contract> : (!fir.ref<i8>) -> () | ||
| ! CHECK: } | ||
| ! CHECK: } do { | ||
| ! CHECK: hlfir.region_assign { | ||
| ! CHECK: %[[VAL_24:.*]] = hlfir.exactly_once : f32 { | ||
| ! CHECK: %[[VAL_28:.*]] = hlfir.elemental %{{.*}} unordered : (!fir.shape<1>) -> !hlfir.expr<?xf32> { | ||
| ! CHECK: } | ||
| ! CHECK-NOT: hlfir.exactly_once | ||
| ! CHECK: %[[VAL_35:.*]] = fir.call @_QPreal_func2() fastmath<contract> : () -> f32 | ||
| ! CHECK: %[[VAL_36:.*]] = hlfir.elemental %{{.*}} unordered : (!fir.shape<1>) -> !hlfir.expr<?xf32> { | ||
| ! CHECK: ^bb0(%[[VAL_37:.*]]: index): | ||
| ! CHECK: %[[VAL_38:.*]] = hlfir.apply %[[VAL_28]], %[[VAL_37]] : (!hlfir.expr<?xf32>, index) -> f32 | ||
| ! CHECK: %[[VAL_39:.*]] = arith.addf %[[VAL_38]], %[[VAL_35]] fastmath<contract> : f32 | ||
| ! CHECK: hlfir.yield_element %[[VAL_39]] : f32 | ||
| ! CHECK: } | ||
| ! CHECK: %[[VAL_41:.*]] = fir.call @_QPreal_func | ||
| ! CHECK: hlfir.yield %[[VAL_41]] : f32 cleanup { | ||
| ! CHECK: hlfir.destroy %[[VAL_36]] : !hlfir.expr<?xf32> | ||
| ! CHECK: hlfir.destroy %[[VAL_28]] : !hlfir.expr<?xf32> | ||
| ! CHECK: } | ||
| ! CHECK: } | ||
| ! CHECK: %[[VAL_45:.*]] = hlfir.elemental %{{.*}} unordered : (!fir.shape<1>) -> !hlfir.expr<?xf32> { | ||
| ! CHECK: arith.addf | ||
| ! CHECK-NOT: hlfir.exactly_once | ||
| ! CHECK: } | ||
| ! CHECK: %[[VAL_53:.*]] = hlfir.elemental %{{.*}} unordered : (!fir.shape<1>) -> !hlfir.expr<?xf32> { | ||
| ! CHECK: fir.call @_QPelem_func | ||
| ! CHECK: } | ||
| ! CHECK: %[[VAL_57:.*]] = hlfir.elemental %{{.*}} unordered : (!fir.shape<1>) -> !hlfir.expr<?xf32> { | ||
| ! CHECK: arith.addf | ||
| ! CHECK: } | ||
| ! CHECK: hlfir.yield %[[VAL_57]] : !hlfir.expr<?xf32> cleanup { | ||
| ! CHECK: hlfir.destroy %[[VAL_57]] : !hlfir.expr<?xf32> | ||
| ! CHECK: hlfir.destroy %[[VAL_53]] : !hlfir.expr<?xf32> | ||
| ! CHECK: hlfir.destroy %[[VAL_45]] : !hlfir.expr<?xf32> | ||
| ! CHECK: } | ||
| ! CHECK: } to { | ||
| ! CHECK: hlfir.yield %{{.*}} : !fir.box<!fir.array<?xf32>> | ||
| ! CHECK: } | ||
| ! CHECK: hlfir.elsewhere mask { | ||
| ! CHECK: %[[VAL_62:.*]] = hlfir.exactly_once : !hlfir.expr<100x!fir.logical<4>> { | ||
| ! CHECK: %[[VAL_72:.*]] = fir.call @llvm.stacksave.p0() fastmath<contract> : () -> !fir.ref<i8> | ||
| ! CHECK: fir.call @_QPlogical_func2() fastmath<contract> : () -> !fir.array<100x!fir.logical<4>> | ||
| ! CHECK: hlfir.yield %{{.*}} : !hlfir.expr<100x!fir.logical<4>> cleanup { | ||
| ! CHECK: fir.call @llvm.stackrestore.p0(%[[VAL_72]]) fastmath<contract> : (!fir.ref<i8>) -> () | ||
| ! CHECK: } | ||
| ! CHECK: } | ||
| ! CHECK: hlfir.yield %[[VAL_62]] : !hlfir.expr<100x!fir.logical<4>> | ||
| ! CHECK: } do { | ||
| ! CHECK: hlfir.region_assign { | ||
| ! CHECK: hlfir.yield %{{.*}} : !fir.box<!fir.array<?xf32>> | ||
| ! CHECK: } to { | ||
| ! CHECK: %[[VAL_80:.*]] = hlfir.exactly_once : i32 { | ||
| ! CHECK: %[[VAL_81:.*]] = fir.call @_QPifoo() fastmath<contract> : () -> i32 | ||
| ! CHECK: hlfir.yield %[[VAL_81]] : i32 | ||
| ! CHECK: } | ||
| ! CHECK: hlfir.yield %{{.*}} : !fir.box<!fir.array<?xf32>> | ||
| ! CHECK: } | ||
| ! CHECK: } | ||
| ! CHECK: } | ||
| ! CHECK: return | ||
| ! CHECK: } | ||
|
|
||
| subroutine test_where_in_forall(a, b, c) | ||
| real, dimension(:, :) :: a, b, c | ||
| interface | ||
| pure function pure_logical_func1() | ||
| logical :: pure_logical_func1(100) | ||
| end function | ||
| pure function pure_logical_func2() | ||
| logical :: pure_logical_func2(100) | ||
| end function | ||
| real pure elemental function pure_elem_func(x) | ||
| real, intent(in) :: x | ||
| end function | ||
| integer pure function pure_ifoo() | ||
| end function | ||
| end interface | ||
| forall(i=1:10) | ||
| where (pure_logical_func1()) | ||
| a(2*i, :) = b(i, :) + pure_real_func(a(i,:)+b(i,:)+pure_real_func2()) + pure_elem_func(a(i,:)) | ||
| elsewhere(pure_logical_func2()) | ||
| a(2*i, 1:pure_ifoo()) = c(i, :) | ||
| end where | ||
| end forall | ||
| end subroutine | ||
| ! CHECK-LABEL: func.func @_QPtest_where_in_forall( | ||
| ! CHECK: hlfir.forall lb { | ||
| ! CHECK: hlfir.yield %{{.*}} : i32 | ||
| ! CHECK: } ub { | ||
| ! CHECK: hlfir.yield %{{.*}} : i32 | ||
| ! CHECK: } (%[[VAL_10:.*]]: i32) { | ||
| ! CHECK: %[[VAL_11:.*]] = hlfir.forall_index "i" %[[VAL_10]] : (i32) -> !fir.ref<i32> | ||
| ! CHECK: hlfir.where { | ||
| ! CHECK: %[[VAL_21:.*]] = fir.call @llvm.stacksave.p0() fastmath<contract> : () -> !fir.ref<i8> | ||
| ! CHECK-NOT: hlfir.exactly_once | ||
| ! CHECK: %[[VAL_23:.*]] = fir.call @_QPpure_logical_func1() fastmath<contract> : () -> !fir.array<100x!fir.logical<4>> | ||
| ! CHECK: hlfir.yield %{{.*}} : !hlfir.expr<100x!fir.logical<4>> cleanup { | ||
| ! CHECK: fir.call @llvm.stackrestore.p0(%[[VAL_21]]) fastmath<contract> : (!fir.ref<i8>) -> () | ||
| ! CHECK: } | ||
| ! CHECK: } do { | ||
| ! CHECK: hlfir.region_assign { | ||
| ! CHECK: %[[VAL_41:.*]] = hlfir.designate | ||
| ! CHECK: %[[VAL_42:.*]] = hlfir.exactly_once : f32 { | ||
| ! CHECK: hlfir.designate | ||
| ! CHECK: hlfir.designate | ||
| ! CHECK: %[[VAL_71:.*]] = hlfir.elemental %{{.*}} unordered : (!fir.shape<1>) -> !hlfir.expr<?xf32> { | ||
| ! CHECK: arith.addf | ||
| ! CHECK: } | ||
| ! CHECK-NOT: hlfir.exactly_once | ||
| ! CHECK: %[[VAL_78:.*]] = fir.call @_QPpure_real_func2() fastmath<contract> : () -> f32 | ||
| ! CHECK: %[[VAL_79:.*]] = hlfir.elemental %{{.*}} unordered : (!fir.shape<1>) -> !hlfir.expr<?xf32> { | ||
| ! CHECK: arith.addf | ||
| ! CHECK: } | ||
| ! CHECK: %[[VAL_84:.*]] = fir.call @_QPpure_real_func( | ||
| ! CHECK: hlfir.yield %[[VAL_84]] : f32 cleanup { | ||
| ! CHECK: hlfir.destroy %[[VAL_79]] : !hlfir.expr<?xf32> | ||
| ! CHECK: hlfir.destroy %[[VAL_71]] : !hlfir.expr<?xf32> | ||
| ! CHECK: } | ||
| ! CHECK: } | ||
| ! CHECK: %[[VAL_85:.*]] = hlfir.elemental %{{.*}} unordered : (!fir.shape<1>) -> !hlfir.expr<?xf32> { | ||
| ! CHECK: arith.addf | ||
| ! CHECK: } | ||
| ! CHECK-NOT: hlfir.exactly_once | ||
| ! CHECK: %[[VAL_104:.*]] = hlfir.elemental %{{.*}} unordered : (!fir.shape<1>) -> !hlfir.expr<?xf32> { | ||
| ! CHECK: ^bb0(%[[VAL_105:.*]]: index): | ||
| ! CHECK-NOT: hlfir.exactly_once | ||
| ! CHECK: fir.call @_QPpure_elem_func | ||
| ! CHECK: } | ||
| ! CHECK: %[[VAL_108:.*]] = hlfir.elemental %{{.*}} unordered : (!fir.shape<1>) -> !hlfir.expr<?xf32> { | ||
| ! CHECK: arith.addf | ||
| ! CHECK: } | ||
| ! CHECK: hlfir.yield %[[VAL_108]] : !hlfir.expr<?xf32> cleanup { | ||
| ! CHECK: hlfir.destroy %[[VAL_108]] : !hlfir.expr<?xf32> | ||
| ! CHECK: hlfir.destroy %[[VAL_104]] : !hlfir.expr<?xf32> | ||
| ! CHECK: hlfir.destroy %[[VAL_85]] : !hlfir.expr<?xf32> | ||
| ! CHECK: } | ||
| ! CHECK: } to { | ||
| ! CHECK: hlfir.designate | ||
| ! CHECK: hlfir.yield %{{.*}} : !fir.box<!fir.array<?xf32>> | ||
| ! CHECK: } | ||
| ! CHECK: hlfir.elsewhere mask { | ||
| ! CHECK: %[[VAL_129:.*]] = hlfir.exactly_once : !hlfir.expr<100x!fir.logical<4>> { | ||
| ! CHECK: %[[VAL_139:.*]] = fir.call @llvm.stacksave.p0() fastmath<contract> : () -> !fir.ref<i8> | ||
| ! CHECK: %[[VAL_141:.*]] = fir.call @_QPpure_logical_func2() fastmath<contract> : () -> !fir.array<100x!fir.logical<4>> | ||
| ! CHECK: hlfir.yield %{{.*}} : !hlfir.expr<100x!fir.logical<4>> cleanup { | ||
| ! CHECK: fir.call @llvm.stackrestore.p0(%[[VAL_139]]) fastmath<contract> : (!fir.ref<i8>) -> () | ||
| ! CHECK: } | ||
| ! CHECK: } | ||
| ! CHECK: hlfir.yield %[[VAL_129]] : !hlfir.expr<100x!fir.logical<4>> | ||
| ! CHECK: } do { | ||
| ! CHECK: hlfir.region_assign { | ||
| ! CHECK: hlfir.designate | ||
| ! CHECK: hlfir.yield %{{.*}} : !fir.box<!fir.array<?xf32>> | ||
| ! CHECK: } to { | ||
| ! CHECK: %[[VAL_165:.*]] = hlfir.exactly_once : i32 { | ||
| ! CHECK: %[[VAL_166:.*]] = fir.call @_QPpure_ifoo() fastmath<contract> : () -> i32 | ||
| ! CHECK: hlfir.yield %[[VAL_166]] : i32 | ||
| ! CHECK: } | ||
| ! CHECK: hlfir.designate | ||
| ! CHECK: hlfir.yield %{{.*}} : !fir.box<!fir.array<?xf32>> | ||
| ! CHECK: } | ||
| ! CHECK: } | ||
| ! CHECK: } | ||
| ! CHECK: } | ||
| ! CHECK: return | ||
| ! CHECK: } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| //===-- Definition of macros from errno.h ---------------------------------===// | ||
| // | ||
| // 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 | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #ifndef LLVM_LIBC_HDR_ERRNO_MACROS_H | ||
| #define LLVM_LIBC_HDR_ERRNO_MACROS_H | ||
|
|
||
| #ifdef LIBC_FULL_BUILD | ||
|
|
||
| #ifdef __linux__ | ||
| #include <linux/errno.h> | ||
|
|
||
| #include "llvm-libc-macros/error-number-macros.h" | ||
| #else // __linux__ | ||
| #include "llvm-libc-macros/generic-error-number-macros.h" | ||
| #endif | ||
|
|
||
| #else // Overlay mode | ||
|
|
||
| #include <errno.h> | ||
|
|
||
| #endif // LLVM_LIBC_FULL_BUILD | ||
|
|
||
| #endif // LLVM_LIBC_HDR_ERRNO_MACROS_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| #ifndef LLVM_LIBC_MACROS_ERROR_NUMBER_MACROS_H | ||
| #define LLVM_LIBC_MACROS_ERROR_NUMBER_MACROS_H | ||
|
|
||
| #ifdef __linux__ | ||
| #include "linux/error-number-macros.h" | ||
| #endif | ||
|
|
||
| #endif // LLVM_LIBC_MACROS_ERROR_NUMBER_MACROS_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| #ifndef LLVM_LIBC_MACROS_LINUX_ERROR_NUMBER_MACROS_H | ||
| #define LLVM_LIBC_MACROS_LINUX_ERROR_NUMBER_MACROS_H | ||
|
|
||
| #if defined(__mips__) | ||
| #include "mips/error-number-macros.h" | ||
|
|
||
| #elif defined(__sparc__) | ||
| #include "sparc/error-number-macros.h" | ||
|
|
||
| #else | ||
| #ifndef ECANCELED | ||
| #define ECANCELED 125 | ||
| #endif // ECANCELED | ||
|
|
||
| #ifndef EOWNERDEAD | ||
| #define EOWNERDEAD 130 | ||
| #endif // EOWNERDEAD | ||
|
|
||
| #ifndef ENOTRECOVERABLE | ||
| #define ENOTRECOVERABLE 131 | ||
| #endif // ENOTRECOVERABLE | ||
|
|
||
| #ifndef ERFKILL | ||
| #define ERFKILL 132 | ||
| #endif // ERFKILL | ||
|
|
||
| #ifndef EHWPOISON | ||
| #define EHWPOISON 133 | ||
| #endif // EHWPOISON | ||
| #endif | ||
|
|
||
| #endif // LLVM_LIBC_MACROS_LINUX_ERROR_NUMBER_MACROS_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| add_header( | ||
| error_number_macros | ||
| HDR | ||
| error-number-macros.h | ||
| ) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| #ifndef LLVM_LIBC_MACROS_LINUX_MIPS_ERROR_NUMBER_MACROS_H | ||
| #define LLVM_LIBC_MACROS_LINUX_MIPS_ERROR_NUMBER_MACROS_H | ||
|
|
||
| #ifndef ECANCELED | ||
| #define ECANCELED 158 | ||
| #endif // ECANCELED | ||
|
|
||
| #ifndef EOWNERDEAD | ||
| #define EOWNERDEAD 165 | ||
| #endif // EOWNERDEAD | ||
|
|
||
| #ifndef ENOTRECOVERABLE | ||
| #define ENOTRECOVERABLE 166 | ||
| #endif // ENOTRECOVERABLE | ||
|
|
||
| #ifndef ERFKILL | ||
| #define ERFKILL 167 | ||
| #endif // ERFKILL | ||
|
|
||
| #ifndef EHWPOISON | ||
| #define EHWPOISON 168 | ||
| #endif // EHWPOISON | ||
|
|
||
| #endif // LLVM_LIBC_MACROS_LINUX_MIPS_ERROR_NUMBER_MACROS_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| add_header( | ||
| error_number_macros | ||
| HDR | ||
| error-number-macros.h | ||
| ) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| #ifndef LLVM_LIBC_MACROS_LINUX_SPARC_ERROR_NUMBER_MACROS_H | ||
| #define LLVM_LIBC_MACROS_LINUX_SPARC_ERROR_NUMBER_MACROS_H | ||
|
|
||
| #ifndef ECANCELED | ||
| #define ECANCELED 127 | ||
| #endif // ECANCELED | ||
|
|
||
| #ifndef EOWNERDEAD | ||
| #define EOWNERDEAD 132 | ||
| #endif // EOWNERDEAD | ||
|
|
||
| #ifndef ENOTRECOVERABLE | ||
| #define ENOTRECOVERABLE 133 | ||
| #endif // ENOTRECOVERABLE | ||
|
|
||
| #ifndef ERFKILL | ||
| #define ERFKILL 134 | ||
| #endif // ERFKILL | ||
|
|
||
| #ifndef EHWPOISON | ||
| #define EHWPOISON 135 | ||
| #endif // EHWPOISON | ||
|
|
||
| #endif // LLVM_LIBC_MACROS_LINUX_SPARC_ERROR_NUMBER_MACROS_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| //===--- Linux absolute timeout ---------------------------------*- 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 | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #ifndef LLVM_LIBC_SRC___SUPPORT_TIME_LINUX_ABS_TIMEOUT_H | ||
| #define LLVM_LIBC_SRC___SUPPORT_TIME_LINUX_ABS_TIMEOUT_H | ||
|
|
||
| #include "hdr/time_macros.h" | ||
| #include "hdr/types/struct_timespec.h" | ||
| #include "src/__support/CPP/expected.h" | ||
| #include "src/__support/time/units.h" | ||
|
|
||
| namespace LIBC_NAMESPACE { | ||
| namespace internal { | ||
| // We use AbsTimeout to remind ourselves that the timeout is an absolute time. | ||
| // This is a simple wrapper around the timespec struct that also keeps track of | ||
| // whether the time is in realtime or monotonic time. | ||
| class AbsTimeout { | ||
| timespec timeout; | ||
| bool realtime_flag; | ||
| LIBC_INLINE constexpr explicit AbsTimeout(timespec ts, bool realtime) | ||
| : timeout(ts), realtime_flag(realtime) {} | ||
|
|
||
| public: | ||
| enum class Error { Invalid, BeforeEpoch }; | ||
| LIBC_INLINE const timespec &get_timespec() const { return timeout; } | ||
| LIBC_INLINE bool is_realtime() const { return realtime_flag; } | ||
| LIBC_INLINE static constexpr cpp::expected<AbsTimeout, Error> | ||
| from_timespec(timespec ts, bool realtime) { | ||
| using namespace time_units; | ||
| if (ts.tv_nsec < 0 || ts.tv_nsec >= 1_s_ns) | ||
| return cpp::unexpected<Error>(Error::Invalid); | ||
|
|
||
| // POSIX allows tv_sec to be negative. We interpret this as an expired | ||
| // timeout. | ||
| if (ts.tv_sec < 0) | ||
| return cpp::unexpected<Error>(Error::BeforeEpoch); | ||
|
|
||
| return AbsTimeout{ts, realtime}; | ||
| } | ||
| }; | ||
| } // namespace internal | ||
| } // namespace LIBC_NAMESPACE | ||
|
|
||
| #endif // LLVM_LIBC_SRC___SUPPORT_TIME_LINUX_ABS_TIMEOUT_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| //===--- clock conversion linux implementation ------------------*- 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 | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #ifndef LLVM_LIBC_SRC___SUPPORT_TIME_LINUX_CLOCK_CONVERSION_H | ||
| #define LLVM_LIBC_SRC___SUPPORT_TIME_LINUX_CLOCK_CONVERSION_H | ||
|
|
||
| #include "src/__support/time/linux/clock_gettime.h" | ||
| #include "src/__support/time/units.h" | ||
|
|
||
| namespace LIBC_NAMESPACE { | ||
| namespace internal { | ||
|
|
||
| LIBC_INLINE timespec convert_clock(timespec input, clockid_t from, | ||
| clockid_t to) { | ||
| using namespace time_units; | ||
| timespec from_time; | ||
| timespec to_time; | ||
| timespec output; | ||
| internal::clock_gettime(from, &from_time); | ||
| internal::clock_gettime(to, &to_time); | ||
| output.tv_sec = input.tv_sec - from_time.tv_sec + to_time.tv_sec; | ||
| output.tv_nsec = input.tv_nsec - from_time.tv_nsec + to_time.tv_nsec; | ||
|
|
||
| if (output.tv_nsec > 1_s_ns) { | ||
| output.tv_sec++; | ||
| output.tv_nsec -= 1_s_ns; | ||
| } else if (output.tv_nsec < 0) { | ||
| output.tv_sec--; | ||
| output.tv_nsec += 1_s_ns; | ||
| } | ||
| return output; | ||
| } | ||
|
|
||
| } // namespace internal | ||
| } // namespace LIBC_NAMESPACE | ||
|
|
||
| #endif // LLVM_LIBC_SRC___SUPPORT_TIME_LINUX_CLOCK_CONVERSION_H |