summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVitaly Buka <vitalybuka@google.com>2024-01-05 18:41:18 -0800
committerVitaly Buka <vitalybuka@google.com>2024-01-05 18:41:18 -0800
commit6faf51a48a2185db89dddafca73fd8a23488c5c8 (patch)
treedf63a41fccb16f15fe385c31ab7cdc8cb4bb5d5d
parent672bf3af16af61d513c4a109c033c844b0562d54 (diff)
parent23aabdd66f78dc28919c4a85d4bdcbf7b0dd89f7 (diff)
Created using spr 1.3.4 [skip ci]
-rw-r--r--compiler-rt/lib/ubsan/ubsan_diag.cpp2
-rw-r--r--compiler-rt/test/ubsan/TestCases/Misc/print_summary.c4
-rw-r--r--flang/test/Lower/OpenACC/acc-reduction.f90539
-rw-r--r--libcxx/docs/FeatureTestMacroTable.rst2
-rw-r--r--libcxx/docs/ReleaseNotes/18.rst1
-rw-r--r--libcxx/docs/Status/Cxx2cPapers.csv2
-rw-r--r--libcxx/include/fstream50
-rw-r--r--libcxx/include/version2
-rw-r--r--libcxx/src/CMakeLists.txt1
-rw-r--r--libcxx/src/fstream.cpp37
-rw-r--r--libcxx/test/std/input.output/file.streams/fstreams/filebuf.members/native_handle.assert.pass.cpp32
-rw-r--r--libcxx/test/std/input.output/file.streams/fstreams/filebuf.members/native_handle.pass.cpp58
-rw-r--r--libcxx/test/std/input.output/file.streams/fstreams/filebuf/types.pass.cpp9
-rw-r--r--libcxx/test/std/input.output/file.streams/fstreams/fstream.members/native_handle.assert.pass.cpp32
-rw-r--r--libcxx/test/std/input.output/file.streams/fstreams/fstream.members/native_handle.pass.cpp27
-rw-r--r--libcxx/test/std/input.output/file.streams/fstreams/fstream/types.pass.cpp9
-rw-r--r--libcxx/test/std/input.output/file.streams/fstreams/ifstream.members/native_handle.assert.pass.cpp32
-rw-r--r--libcxx/test/std/input.output/file.streams/fstreams/ifstream.members/native_handle.pass.cpp27
-rw-r--r--libcxx/test/std/input.output/file.streams/fstreams/ifstream/types.pass.cpp9
-rw-r--r--libcxx/test/std/input.output/file.streams/fstreams/native_handle_test_helpers.h97
-rw-r--r--libcxx/test/std/input.output/file.streams/fstreams/ofstream.members/native_handle.assert.pass.cpp32
-rw-r--r--libcxx/test/std/input.output/file.streams/fstreams/ofstream.members/native_handle.pass.cpp27
-rw-r--r--libcxx/test/std/input.output/file.streams/fstreams/ofstream/types.pass.cpp9
-rw-r--r--libcxx/test/std/input.output/file.streams/fstreams/types.h10
-rw-r--r--libcxx/test/std/language.support/support.limits/support.limits.general/fstream.version.compile.pass.cpp16
-rw-r--r--libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp16
-rwxr-xr-xlibcxx/utils/generate_feature_test_macro_components.py1
-rw-r--r--llvm/include/llvm/Analysis/MemoryBuiltins.h171
-rw-r--r--llvm/include/llvm/CodeGen/CodeGenPassBuilder.h4
-rw-r--r--llvm/include/llvm/CodeGen/MachinePassRegistry.def2
-rw-r--r--llvm/include/llvm/CodeGen/ShadowStackGCLowering.h24
-rw-r--r--llvm/lib/Analysis/MemoryBuiltins.cpp308
-rw-r--r--llvm/lib/CodeGen/ShadowStackGCLowering.cpp97
-rw-r--r--llvm/lib/Passes/PassBuilder.cpp1
-rw-r--r--llvm/lib/Passes/PassRegistry.def1
-rw-r--r--llvm/lib/Transforms/IPO/AttributorAttributes.cpp6
-rw-r--r--llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp12
-rw-r--r--llvm/lib/Transforms/Instrumentation/BoundsChecking.cpp8
-rw-r--r--llvm/utils/gn/secondary/libcxx/src/BUILD.gn3
39 files changed, 661 insertions, 1059 deletions
diff --git a/compiler-rt/lib/ubsan/ubsan_diag.cpp b/compiler-rt/lib/ubsan/ubsan_diag.cpp
index aac270415318..67e884e4916c 100644
--- a/compiler-rt/lib/ubsan/ubsan_diag.cpp
+++ b/compiler-rt/lib/ubsan/ubsan_diag.cpp
@@ -88,7 +88,7 @@ static void MaybeReportErrorSummary(Location Loc, ErrorType Type) {
AI.file = internal_strdup(SLoc.getFilename());
AI.line = SLoc.getLine();
AI.column = SLoc.getColumn();
- AI.function = internal_strdup(""); // Avoid printing ?? as function name.
+ AI.function = nullptr;
ReportErrorSummary(ErrorKind, AI, GetSanititizerToolName());
AI.Clear();
return;
diff --git a/compiler-rt/test/ubsan/TestCases/Misc/print_summary.c b/compiler-rt/test/ubsan/TestCases/Misc/print_summary.c
index b67a0614dd2f..17885094b6ad 100644
--- a/compiler-rt/test/ubsan/TestCases/Misc/print_summary.c
+++ b/compiler-rt/test/ubsan/TestCases/Misc/print_summary.c
@@ -2,8 +2,8 @@
// RUN: %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-DEFAULT
// RUN: %env_ubsan_opts=print_summary=0 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-NO_SUMMARY
-// CHECK-DEFAULT: SUMMARY: UndefinedBehaviorSanitizer: {{.*}}
-// CHECK-NO_SUMMARY-NOT: SUMMARY: UndefinedBehaviorSanitizer: {{.*}}
+// CHECK-DEFAULT: SUMMARY: UndefinedBehaviorSanitizer: {{.*}}print_summary.c{{[:0-9 ]*$}}
+// CHECK-NO_SUMMARY-NOT: SUMMARY: UndefinedBehaviorSanitizer:
int main(int argc, char **argv) {
int arr[argc - 2];
diff --git a/flang/test/Lower/OpenACC/acc-reduction.f90 b/flang/test/Lower/OpenACC/acc-reduction.f90
index dcfa77c9f97d..fe04c3114b7e 100644
--- a/flang/test/Lower/OpenACC/acc-reduction.f90
+++ b/flang/test/Lower/OpenACC/acc-reduction.f90
@@ -1,35 +1,34 @@
! This test checks lowering of OpenACC reduction clause.
-! RUN: bbc -fopenacc -emit-fir -hlfir=false %s -o - | FileCheck %s --check-prefixes=CHECK,FIR
-! RUN: bbc -fopenacc -emit-hlfir %s -o - | FileCheck %s --check-prefixes=CHECK,HLFIR
+! RUN: bbc -fopenacc -emit-hlfir %s -o - | FileCheck %s --check-prefixes=CHECK
! CHECK-LABEL: acc.reduction.recipe @reduction_max_ref_UxUxf32 : !fir.ref<!fir.array<?x?xf32>> reduction_operator <max> init {
! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref<!fir.array<?x?xf32>>, %[[ARG1:.*]]: index, %[[ARG2:.*]]: index):
-! HLFIR: %[[CST:.*]] = arith.constant -1.401300e-45 : f32
-! HLFIR: %[[SHAPE:.*]] = fir.shape %arg1, %arg2 : (index, index) -> !fir.shape<2>
-! HLFIR: %[[TEMP:.*]] = fir.alloca !fir.array<?x?xf32>, %arg1, %arg2
-! HLFIR: %[[DECL:.*]]:2 = hlfir.declare %[[TEMP]](%[[SHAPE]]) {uniq_name = "acc.reduction.init"} : (!fir.ref<!fir.array<?x?xf32>>, !fir.shape<2>) -> (!fir.box<!fir.array<?x?xf32>>, !fir.ref<!fir.array<?x?xf32>>)
-! HLFIR: hlfir.assign %[[CST]] to %[[DECL]]#0 : f32, !fir.box<!fir.array<?x?xf32>>
-! HLFIR: acc.yield %[[DECL]]#0 : !fir.box<!fir.array<?x?xf32>>
+! CHECK: %[[CST:.*]] = arith.constant -1.401300e-45 : f32
+! CHECK: %[[SHAPE:.*]] = fir.shape %arg1, %arg2 : (index, index) -> !fir.shape<2>
+! CHECK: %[[TEMP:.*]] = fir.alloca !fir.array<?x?xf32>, %arg1, %arg2
+! CHECK: %[[DECL:.*]]:2 = hlfir.declare %[[TEMP]](%[[SHAPE]]) {uniq_name = "acc.reduction.init"} : (!fir.ref<!fir.array<?x?xf32>>, !fir.shape<2>) -> (!fir.box<!fir.array<?x?xf32>>, !fir.ref<!fir.array<?x?xf32>>)
+! CHECK: hlfir.assign %[[CST]] to %[[DECL]]#0 : f32, !fir.box<!fir.array<?x?xf32>>
+! CHECK: acc.yield %[[DECL]]#0 : !fir.box<!fir.array<?x?xf32>>
! CHECK: } combiner {
! CHECK: ^bb0(%[[V1:.*]]: !fir.ref<!fir.array<?x?xf32>>, %[[V2:.*]]: !fir.ref<!fir.array<?x?xf32>>, %[[LB0:.*]]: index, %[[UB0:.*]]: index, %[[STEP0:.*]]: index, %[[LB1:.*]]: index, %[[UB1:.*]]: index, %[[STEP1:.*]]: index):
-! HLFIR: %[[SHAPE:.*]] = fir.shape %{{.*}}, %{{.*}} : (index, index) -> !fir.shape<2>
-! HLFIR: %[[DECL_V1:.*]]:2 = hlfir.declare %[[V1]](%[[SHAPE]]) {uniq_name = ""} : (!fir.ref<!fir.array<?x?xf32>>, !fir.shape<2>) -> (!fir.box<!fir.array<?x?xf32>>, !fir.ref<!fir.array<?x?xf32>>)
-! HLFIR: %[[DECL_V2:.*]]:2 = hlfir.declare %[[V2]](%[[SHAPE]]) {uniq_name = ""} : (!fir.ref<!fir.array<?x?xf32>>, !fir.shape<2>) -> (!fir.box<!fir.array<?x?xf32>>, !fir.ref<!fir.array<?x?xf32>>)
-! HLFIR: %[[DES_V1:.*]] = hlfir.designate %[[DECL_V1]]#0 (%arg2:%arg3:%arg4, %arg5:%arg6:%arg7) shape %10 : (!fir.box<!fir.array<?x?xf32>>, index, index, index, index, index, index, !fir.shape<2>) -> !fir.box<!fir.array<?x?xf32>>
-! HLFIR: %[[DES_V2:.*]] = hlfir.designate %[[DECL_V2]]#0 (%arg2:%arg3:%arg4, %arg5:%arg6:%arg7) shape %10 : (!fir.box<!fir.array<?x?xf32>>, index, index, index, index, index, index, !fir.shape<2>) -> !fir.box<!fir.array<?x?xf32>>
-! HLFIR: %[[ELEMENTAL:.*]] = hlfir.elemental %[[SHAPE]] unordered : (!fir.shape<2>) -> !hlfir.expr<?x?xf32> {
-! HLFIR: ^bb0(%[[ARG0:.*]]: index, %[[ARG1:.*]]: index):
-! HLFIR: %[[D1:.*]] = hlfir.designate %13 (%[[ARG0]], %[[ARG1]]) : (!fir.box<!fir.array<?x?xf32>>, index, index) -> !fir.ref<f32>
-! HLFIR: %[[D2:.*]] = hlfir.designate %14 (%[[ARG0]], %[[ARG1]]) : (!fir.box<!fir.array<?x?xf32>>, index, index) -> !fir.ref<f32>
-! HLFIR: %[[LOAD1:.*]] = fir.load %[[D1]] : !fir.ref<f32>
-! HLFIR: %[[LOAD2:.*]] = fir.load %[[D2]] : !fir.ref<f32>
-! HLFIR: %[[CMP:.*]] = arith.cmpf ogt, %[[LOAD1]], %[[LOAD2]] {{.*}} : f32
-! HLFIR: %[[SELECT:.*]] = arith.select %[[CMP]], %[[LOAD1]], %[[LOAD2]] : f32
-! HLFIR: hlfir.yield_element %[[SELECT]] : f32
-! HLFIR: }
-! HLFIR: hlfir.assign %[[ELEMENTAL]] to %[[DECL_V1]]#0 : !hlfir.expr<?x?xf32>, !fir.box<!fir.array<?x?xf32>>
-! HLFIR: acc.yield %[[V1]] : !fir.ref<!fir.array<?x?xf32>>
+! CHECK: %[[SHAPE:.*]] = fir.shape %{{.*}}, %{{.*}} : (index, index) -> !fir.shape<2>
+! CHECK: %[[DECL_V1:.*]]:2 = hlfir.declare %[[V1]](%[[SHAPE]]) {uniq_name = ""} : (!fir.ref<!fir.array<?x?xf32>>, !fir.shape<2>) -> (!fir.box<!fir.array<?x?xf32>>, !fir.ref<!fir.array<?x?xf32>>)
+! CHECK: %[[DECL_V2:.*]]:2 = hlfir.declare %[[V2]](%[[SHAPE]]) {uniq_name = ""} : (!fir.ref<!fir.array<?x?xf32>>, !fir.shape<2>) -> (!fir.box<!fir.array<?x?xf32>>, !fir.ref<!fir.array<?x?xf32>>)
+! CHECK: %[[DES_V1:.*]] = hlfir.designate %[[DECL_V1]]#0 (%arg2:%arg3:%arg4, %arg5:%arg6:%arg7) shape %10 : (!fir.box<!fir.array<?x?xf32>>, index, index, index, index, index, index, !fir.shape<2>) -> !fir.box<!fir.array<?x?xf32>>
+! CHECK: %[[DES_V2:.*]] = hlfir.designate %[[DECL_V2]]#0 (%arg2:%arg3:%arg4, %arg5:%arg6:%arg7) shape %10 : (!fir.box<!fir.array<?x?xf32>>, index, index, index, index, index, index, !fir.shape<2>) -> !fir.box<!fir.array<?x?xf32>>
+! CHECK: %[[ELEMENTAL:.*]] = hlfir.elemental %[[SHAPE]] unordered : (!fir.shape<2>) -> !hlfir.expr<?x?xf32> {
+! CHECK: ^bb0(%[[ARG0:.*]]: index, %[[ARG1:.*]]: index):
+! CHECK: %[[D1:.*]] = hlfir.designate %13 (%[[ARG0]], %[[ARG1]]) : (!fir.box<!fir.array<?x?xf32>>, index, index) -> !fir.ref<f32>
+! CHECK: %[[D2:.*]] = hlfir.designate %14 (%[[ARG0]], %[[ARG1]]) : (!fir.box<!fir.array<?x?xf32>>, index, index) -> !fir.ref<f32>
+! CHECK: %[[LOAD1:.*]] = fir.load %[[D1]] : !fir.ref<f32>
+! CHECK: %[[LOAD2:.*]] = fir.load %[[D2]] : !fir.ref<f32>
+! CHECK: %[[CMP:.*]] = arith.cmpf ogt, %[[LOAD1]], %[[LOAD2]] {{.*}} : f32
+! CHECK: %[[SELECT:.*]] = arith.select %[[CMP]], %[[LOAD1]], %[[LOAD2]] : f32
+! CHECK: hlfir.yield_element %[[SELECT]] : f32
+! CHECK: }
+! CHECK: hlfir.assign %[[ELEMENTAL]] to %[[DECL_V1]]#0 : !hlfir.expr<?x?xf32>, !fir.box<!fir.array<?x?xf32>>
+! CHECK: acc.yield %[[V1]] : !fir.ref<!fir.array<?x?xf32>>
! CHECK: }
! CHECK-LABEL: acc.reduction.recipe @reduction_max_box_ptr_Uxf32 : !fir.box<!fir.ptr<!fir.array<?xf32>>> reduction_operator <max> init {
@@ -40,111 +39,111 @@
! CHECK-LABEL: acc.reduction.recipe @reduction_max_box_heap_Uxf32 : !fir.box<!fir.heap<!fir.array<?xf32>>> reduction_operator <max> init {
! CHECK: ^bb0(%[[ARG0:.*]]: !fir.box<!fir.heap<!fir.array<?xf32>>>):
-! HLFIR: %[[CST:.*]] = arith.constant -1.401300e-45 : f32
-! HLFIR: %[[C0:.*]] = arith.constant 0 : index
-! HLFIR: %[[BOX_DIMS:.*]]:3 = fir.box_dims %[[ARG0]], %[[C0]] : (!fir.box<!fir.heap<!fir.array<?xf32>>>, index) -> (index, index, index)
-! HLFIR: %[[SHAPE:.*]] = fir.shape %[[BOX_DIMS]]#1 : (index) -> !fir.shape<1>
-! HLFIR: %[[TEMP:.*]] = fir.allocmem !fir.array<?xf32>, %[[BOX_DIMS]]#1 {bindc_name = ".tmp", uniq_name = ""}
-! HLFIR: %[[DECLARE:.*]]:2 = hlfir.declare %2(%1) {uniq_name = ".tmp"} : (!fir.heap<!fir.array<?xf32>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xf32>>, !fir.heap<!fir.array<?xf32>>)
-! HLFIR: hlfir.assign %[[CST]] to %[[DECLARE]]#0 : f32, !fir.box<!fir.array<?xf32>>
-! HLFIR: acc.yield %[[DECLARE]]#0 : !fir.box<!fir.array<?xf32>>
+! CHECK: %[[CST:.*]] = arith.constant -1.401300e-45 : f32
+! CHECK: %[[C0:.*]] = arith.constant 0 : index
+! CHECK: %[[BOX_DIMS:.*]]:3 = fir.box_dims %[[ARG0]], %[[C0]] : (!fir.box<!fir.heap<!fir.array<?xf32>>>, index) -> (index, index, index)
+! CHECK: %[[SHAPE:.*]] = fir.shape %[[BOX_DIMS]]#1 : (index) -> !fir.shape<1>
+! CHECK: %[[TEMP:.*]] = fir.allocmem !fir.array<?xf32>, %[[BOX_DIMS]]#1 {bindc_name = ".tmp", uniq_name = ""}
+! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %2(%1) {uniq_name = ".tmp"} : (!fir.heap<!fir.array<?xf32>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xf32>>, !fir.heap<!fir.array<?xf32>>)
+! CHECK: hlfir.assign %[[CST]] to %[[DECLARE]]#0 : f32, !fir.box<!fir.array<?xf32>>
+! CHECK: acc.yield %[[DECLARE]]#0 : !fir.box<!fir.array<?xf32>>
! CHECK: } combiner {
-! HLFIR: ^bb0(%[[ARG0:.*]]: !fir.box<!fir.heap<!fir.array<?xf32>>>, %[[ARG1:.*]]: !fir.box<!fir.heap<!fir.array<?xf32>>>, %[[ARG2:.*]]: index, %[[ARG3:.*]]: index, %[[ARG4:.*]]: index):
-! HLFIR: %[[SHAPE:.*]] = fir.shape %{{.*}} : (index) -> !fir.shape<1>
-! HLFIR: %[[DES_V1:.*]] = hlfir.designate %[[ARG0]] (%[[ARG2]]:%[[ARG3]]:%[[ARG4]]) shape %[[SHAPE]] : (!fir.box<!fir.heap<!fir.array<?xf32>>>, index, index, index, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?xf32>>>
-! HLFIR: %[[DES_V2:.*]] = hlfir.designate %[[ARG1]] (%[[ARG2]]:%[[ARG3]]:%[[ARG4]]) shape %[[SHAPE]] : (!fir.box<!fir.heap<!fir.array<?xf32>>>, index, index, index, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?xf32>>>
-! HLFIR: %[[ELEMENTAL:.*]] = hlfir.elemental %[[SHAPE]] unordered : (!fir.shape<1>) -> !hlfir.expr<?xf32> {
-! HLFIR: ^bb0(%[[IV:.*]]: index):
-! HLFIR: %[[V1:.*]] = hlfir.designate %[[DES_V1]] (%[[IV]]) : (!fir.box<!fir.heap<!fir.array<?xf32>>>, index) -> !fir.ref<f32>
-! HLFIR: %[[V2:.*]] = hlfir.designate %[[DES_V2]] (%[[IV]]) : (!fir.box<!fir.heap<!fir.array<?xf32>>>, index) -> !fir.ref<f32>
-! HLFIR: %[[LOAD_V1:.*]] = fir.load %[[V1]] : !fir.ref<f32>
-! HLFIR: %[[LOAD_V2:.*]] = fir.load %[[V2]] : !fir.ref<f32>
-! HLFIR: %[[CMP:.*]] = arith.cmpf ogt, %[[LOAD_V1]], %[[LOAD_V2]] {{.*}} : f32
-! HLFIR: %[[SELECT:.*]] = arith.select %[[CMP]], %[[LOAD_V1]], %[[LOAD_V2]] : f32
-! HLFIR: hlfir.yield_element %[[SELECT]] : f32
-! HLFIR: }
-! HLFIR: hlfir.assign %[[ELEMENTAL]] to %[[ARG0]] : !hlfir.expr<?xf32>, !fir.box<!fir.heap<!fir.array<?xf32>>>
-! HLFIR: acc.yield %[[ARG0]] : !fir.box<!fir.heap<!fir.array<?xf32>>>
+! CHECK: ^bb0(%[[ARG0:.*]]: !fir.box<!fir.heap<!fir.array<?xf32>>>, %[[ARG1:.*]]: !fir.box<!fir.heap<!fir.array<?xf32>>>, %[[ARG2:.*]]: index, %[[ARG3:.*]]: index, %[[ARG4:.*]]: index):
+! CHECK: %[[SHAPE:.*]] = fir.shape %{{.*}} : (index) -> !fir.shape<1>
+! CHECK: %[[DES_V1:.*]] = hlfir.designate %[[ARG0]] (%[[ARG2]]:%[[ARG3]]:%[[ARG4]]) shape %[[SHAPE]] : (!fir.box<!fir.heap<!fir.array<?xf32>>>, index, index, index, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?xf32>>>
+! CHECK: %[[DES_V2:.*]] = hlfir.designate %[[ARG1]] (%[[ARG2]]:%[[ARG3]]:%[[ARG4]]) shape %[[SHAPE]] : (!fir.box<!fir.heap<!fir.array<?xf32>>>, index, index, index, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?xf32>>>
+! CHECK: %[[ELEMENTAL:.*]] = hlfir.elemental %[[SHAPE]] unordered : (!fir.shape<1>) -> !hlfir.expr<?xf32> {
+! CHECK: ^bb0(%[[IV:.*]]: index):
+! CHECK: %[[V1:.*]] = hlfir.designate %[[DES_V1]] (%[[IV]]) : (!fir.box<!fir.heap<!fir.array<?xf32>>>, index) -> !fir.ref<f32>
+! CHECK: %[[V2:.*]] = hlfir.designate %[[DES_V2]] (%[[IV]]) : (!fir.box<!fir.heap<!fir.array<?xf32>>>, index) -> !fir.ref<f32>
+! CHECK: %[[LOAD_V1:.*]] = fir.load %[[V1]] : !fir.ref<f32>
+! CHECK: %[[LOAD_V2:.*]] = fir.load %[[V2]] : !fir.ref<f32>
+! CHECK: %[[CMP:.*]] = arith.cmpf ogt, %[[LOAD_V1]], %[[LOAD_V2]] {{.*}} : f32
+! CHECK: %[[SELECT:.*]] = arith.select %[[CMP]], %[[LOAD_V1]], %[[LOAD_V2]] : f32
+! CHECK: hlfir.yield_element %[[SELECT]] : f32
+! CHECK: }
+! CHECK: hlfir.assign %[[ELEMENTAL]] to %[[ARG0]] : !hlfir.expr<?xf32>, !fir.box<!fir.heap<!fir.array<?xf32>>>
+! CHECK: acc.yield %[[ARG0]] : !fir.box<!fir.heap<!fir.array<?xf32>>>
! CHECK: }
! CHECK-LABEL: acc.reduction.recipe @reduction_add_section_lb1.ub3_box_Uxi32 : !fir.box<!fir.array<?xi32>> reduction_operator <add> init {
! CHECK: ^bb0(%[[ARG0:.*]]: !fir.box<!fir.array<?xi32>>):
-! HLFIR: %[[BOX_DIMS:.*]]:3 = fir.box_dims %[[ARG0]], %c0{{.*}} : (!fir.box<!fir.array<?xi32>>, index) -> (index, index, index)
-! HLFIR: %[[SHAPE:.*]] = fir.shape %[[BOX_DIMS]]#1 : (index) -> !fir.shape<1>
-! HLFIR: %[[TEMP:.*]] = fir.allocmem !fir.array<?xi32>, %0#1 {bindc_name = ".tmp", uniq_name = ""}
-! HLFIR: %[[DECLARE:.*]]:2 = hlfir.declare %[[TEMP]](%[[SHAPE]]) {uniq_name = ".tmp"} : (!fir.heap<!fir.array<?xi32>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xi32>>, !fir.heap<!fir.array<?xi32>>)
-! HLFIR: hlfir.assign %c0{{.*}} to %[[DECLARE]]#0 : i32, !fir.box<!fir.array<?xi32>>
-! HLFIR: acc.yield %[[DECLARE]]#0 : !fir.box<!fir.array<?xi32>>
+! CHECK: %[[BOX_DIMS:.*]]:3 = fir.box_dims %[[ARG0]], %c0{{.*}} : (!fir.box<!fir.array<?xi32>>, index) -> (index, index, index)
+! CHECK: %[[SHAPE:.*]] = fir.shape %[[BOX_DIMS]]#1 : (index) -> !fir.shape<1>
+! CHECK: %[[TEMP:.*]] = fir.allocmem !fir.array<?xi32>, %0#1 {bindc_name = ".tmp", uniq_name = ""}
+! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[TEMP]](%[[SHAPE]]) {uniq_name = ".tmp"} : (!fir.heap<!fir.array<?xi32>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xi32>>, !fir.heap<!fir.array<?xi32>>)
+! CHECK: hlfir.assign %c0{{.*}} to %[[DECLARE]]#0 : i32, !fir.box<!fir.array<?xi32>>
+! CHECK: acc.yield %[[DECLARE]]#0 : !fir.box<!fir.array<?xi32>>
! CHECK: } combiner {
! CHECK: ^bb0(%[[ARG0:.*]]: !fir.box<!fir.array<?xi32>>, %[[ARG1:.*]]: !fir.box<!fir.array<?xi32>>):
-! HLFIR: %[[SHAPE:.*]] = fir.shape %{{.*}} : (index) -> !fir.shape<1>
-! HLFIR: %[[DES1:.*]] = hlfir.designate %[[ARG0]] shape %[[SHAPE]] : (!fir.box<!fir.array<?xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<?xi32>>
-! HLFIR: %[[DES2:.*]] = hlfir.designate %[[ARG1]] shape %[[SHAPE]] : (!fir.box<!fir.array<?xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<?xi32>>
-! HLFIR: %[[ELEMENTAL:.*]] = hlfir.elemental %[[SHAPE]] unordered : (!fir.shape<1>) -> !hlfir.expr<?xi32> {
-! HLFIR: ^bb0(%[[IV:.*]]: index):
-! HLFIR: %[[DES_V1:.*]] = hlfir.designate %[[DES1]] (%[[IV]]) : (!fir.box<!fir.array<?xi32>>, index) -> !fir.ref<i32>
-! HLFIR: %[[DES_V2:.*]] = hlfir.designate %[[DES2]] (%[[IV]]) : (!fir.box<!fir.array<?xi32>>, index) -> !fir.ref<i32>
-! HLFIR: %[[LOAD_V1:.*]] = fir.load %[[DES_V1]] : !fir.ref<i32>
-! HLFIR: %[[LOAD_V2:.*]] = fir.load %[[DES_V2]] : !fir.ref<i32>
-! HLFIR: %[[COMBINED:.*]] = arith.addi %[[LOAD_V1]], %[[LOAD_V2]] : i32
-! HLFIR: hlfir.yield_element %[[COMBINED]] : i32
-! HLFIR: }
-! HLFIR: hlfir.assign %[[ELEMENTAL]] to %[[ARG0]] : !hlfir.expr<?xi32>, !fir.box<!fir.array<?xi32>>
-! HLFIR: acc.yield %[[ARG0]] : !fir.box<!fir.array<?xi32>>
-! HLFIR: }
+! CHECK: %[[SHAPE:.*]] = fir.shape %{{.*}} : (index) -> !fir.shape<1>
+! CHECK: %[[DES1:.*]] = hlfir.designate %[[ARG0]] shape %[[SHAPE]] : (!fir.box<!fir.array<?xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<?xi32>>
+! CHECK: %[[DES2:.*]] = hlfir.designate %[[ARG1]] shape %[[SHAPE]] : (!fir.box<!fir.array<?xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<?xi32>>
+! CHECK: %[[ELEMENTAL:.*]] = hlfir.elemental %[[SHAPE]] unordered : (!fir.shape<1>) -> !hlfir.expr<?xi32> {
+! CHECK: ^bb0(%[[IV:.*]]: index):
+! CHECK: %[[DES_V1:.*]] = hlfir.designate %[[DES1]] (%[[IV]]) : (!fir.box<!fir.array<?xi32>>, index) -> !fir.ref<i32>
+! CHECK: %[[DES_V2:.*]] = hlfir.designate %[[DES2]] (%[[IV]]) : (!fir.box<!fir.array<?xi32>>, index) -> !fir.ref<i32>
+! CHECK: %[[LOAD_V1:.*]] = fir.load %[[DES_V1]] : !fir.ref<i32>
+! CHECK: %[[LOAD_V2:.*]] = fir.load %[[DES_V2]] : !fir.ref<i32>
+! CHECK: %[[COMBINED:.*]] = arith.addi %[[LOAD_V1]], %[[LOAD_V2]] : i32
+! CHECK: hlfir.yield_element %[[COMBINED]] : i32
+! CHECK: }
+! CHECK: hlfir.assign %[[ELEMENTAL]] to %[[ARG0]] : !hlfir.expr<?xi32>, !fir.box<!fir.array<?xi32>>
+! CHECK: acc.yield %[[ARG0]] : !fir.box<!fir.array<?xi32>>
+! CHECK: }
! CHECK-LABEL: acc.reduction.recipe @reduction_max_box_Uxf32 : !fir.box<!fir.array<?xf32>> reduction_operator <max> init {
! CHECK: ^bb0(%[[ARG0:.*]]: !fir.box<!fir.array<?xf32>>):
! CHECK: %[[INIT_VALUE:.*]] = arith.constant -1.401300e-45 : f32
-! HLFIR: %[[C0:.*]] = arith.constant 0 : index
-! HLFIR: %[[BOX_DIMS:.*]]:3 = fir.box_dims %[[ARG0]], %[[C0]] : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index)
-! HLFIR: %[[SHAPE:.*]] = fir.shape %[[BOX_DIMS]]#1 : (index) -> !fir.shape<1>
-! HLFIR: %[[TEMP:.*]] = fir.allocmem !fir.array<?xf32>, %0#1 {bindc_name = ".tmp", uniq_name = ""}
-! HLFIR: %[[DECLARE:.*]]:2 = hlfir.declare %[[TEMP]](%[[SHAPE]]) {uniq_name = ".tmp"} : (!fir.heap<!fir.array<?xf32>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xf32>>, !fir.heap<!fir.array<?xf32>>)
-! HLFIR: hlfir.assign %[[INIT_VALUE]] to %[[DECLARE]]#0 : f32, !fir.box<!fir.array<?xf32>>
-! HLFIR: acc.yield %[[DECLARE]]#0 : !fir.box<!fir.array<?xf32>>
+! CHECK: %[[C0:.*]] = arith.constant 0 : index
+! CHECK: %[[BOX_DIMS:.*]]:3 = fir.box_dims %[[ARG0]], %[[C0]] : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index)
+! CHECK: %[[SHAPE:.*]] = fir.shape %[[BOX_DIMS]]#1 : (index) -> !fir.shape<1>
+! CHECK: %[[TEMP:.*]] = fir.allocmem !fir.array<?xf32>, %0#1 {bindc_name = ".tmp", uniq_name = ""}
+! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[TEMP]](%[[SHAPE]]) {uniq_name = ".tmp"} : (!fir.heap<!fir.array<?xf32>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xf32>>, !fir.heap<!fir.array<?xf32>>)
+! CHECK: hlfir.assign %[[INIT_VALUE]] to %[[DECLARE]]#0 : f32, !fir.box<!fir.array<?xf32>>
+! CHECK: acc.yield %[[DECLARE]]#0 : !fir.box<!fir.array<?xf32>>
! CHECK: } combiner {
! CHECK: ^bb0(%[[ARG0:.*]]: !fir.box<!fir.array<?xf32>>, %[[ARG1:.*]]: !fir.box<!fir.array<?xf32>>
-! HLFIR: %[[LEFT:.*]] = hlfir.designate %[[ARG0]] (%{{.*}}:%{{.*}}:%{{.*}}) shape %{{.*}} : (!fir.box<!fir.array<?xf32>>, index, index, index, !fir.shape<1>) -> !fir.box<!fir.array<?xf32>>
-! HLFIR: %[[RIGHT:.*]] = hlfir.designate %[[ARG1]] (%{{.*}}:%{{.*}}:%{{.*}}) shape %{{.*}} : (!fir.box<!fir.array<?xf32>>, index, index, index, !fir.shape<1>) -> !fir.box<!fir.array<?xf32>>
-! HLFIR: %[[ELEMENTAL:.*]] = hlfir.elemental %{{.*}} unordered : (!fir.shape<1>) -> !hlfir.expr<?xf32> {
-! HLFIR: ^bb0(%{{.*}}: index):
-! HLFIR: %[[DES_V1:.*]] = hlfir.designate %[[LEFT]] (%{{.*}}) : (!fir.box<!fir.array<?xf32>>, index) -> !fir.ref<f32>
-! HLFIR: %[[DES_V2:.*]] = hlfir.designate %[[RIGHT]] (%{{.*}}) : (!fir.box<!fir.array<?xf32>>, index) -> !fir.ref<f32>
-! HLFIR: %[[LOAD_V1:.*]] = fir.load %[[DES_V1]] : !fir.ref<f32>
-! HLFIR: %[[LOAD_V2:.*]] = fir.load %[[DES_V2]] : !fir.ref<f32>
-! HLFIR: %[[CMPF:.*]] = arith.cmpf ogt, %[[LOAD_V1]], %[[LOAD_V2]] {{.*}} : f32
-! HLFIR: %[[SELECT:.*]] = arith.select %[[CMPF]], %[[LOAD_V1]], %[[LOAD_V2]] : f32
-! HLFIR: hlfir.yield_element %[[SELECT]] : f32
-! HLFIR: }
-! HLFIR: hlfir.assign %[[ELEMENTAL]] to %[[ARG0]] : !hlfir.expr<?xf32>, !fir.box<!fir.array<?xf32>>
+! CHECK: %[[LEFT:.*]] = hlfir.designate %[[ARG0]] (%{{.*}}:%{{.*}}:%{{.*}}) shape %{{.*}} : (!fir.box<!fir.array<?xf32>>, index, index, index, !fir.shape<1>) -> !fir.box<!fir.array<?xf32>>
+! CHECK: %[[RIGHT:.*]] = hlfir.designate %[[ARG1]] (%{{.*}}:%{{.*}}:%{{.*}}) shape %{{.*}} : (!fir.box<!fir.array<?xf32>>, index, index, index, !fir.shape<1>) -> !fir.box<!fir.array<?xf32>>
+! CHECK: %[[ELEMENTAL:.*]] = hlfir.elemental %{{.*}} unordered : (!fir.shape<1>) -> !hlfir.expr<?xf32> {
+! CHECK: ^bb0(%{{.*}}: index):
+! CHECK: %[[DES_V1:.*]] = hlfir.designate %[[LEFT]] (%{{.*}}) : (!fir.box<!fir.array<?xf32>>, index) -> !fir.ref<f32>
+! CHECK: %[[DES_V2:.*]] = hlfir.designate %[[RIGHT]] (%{{.*}}) : (!fir.box<!fir.array<?xf32>>, index) -> !fir.ref<f32>
+! CHECK: %[[LOAD_V1:.*]] = fir.load %[[DES_V1]] : !fir.ref<f32>
+! CHECK: %[[LOAD_V2:.*]] = fir.load %[[DES_V2]] : !fir.ref<f32>
+! CHECK: %[[CMPF:.*]] = arith.cmpf ogt, %[[LOAD_V1]], %[[LOAD_V2]] {{.*}} : f32
+! CHECK: %[[SELECT:.*]] = arith.select %[[CMPF]], %[[LOAD_V1]], %[[LOAD_V2]] : f32
+! CHECK: hlfir.yield_element %[[SELECT]] : f32
+! CHECK: }
+! CHECK: hlfir.assign %[[ELEMENTAL]] to %[[ARG0]] : !hlfir.expr<?xf32>, !fir.box<!fir.array<?xf32>>
! CHECK: acc.yield %[[ARG0]] : !fir.box<!fir.array<?xf32>>
! CHECK: }
! CHECK-LABEL: acc.reduction.recipe @reduction_add_box_Uxi32 : !fir.box<!fir.array<?xi32>> reduction_operator <add> init {
! CHECK: ^bb0(%[[ARG0:.*]]: !fir.box<!fir.array<?xi32>>):
-! HLFIR: %[[INIT_VALUE:.*]] = arith.constant 0 : i32
-! HLFIR: %[[C0:.*]] = arith.constant 0 : index
-! HLFIR: %[[BOX_DIMS:.*]]:3 = fir.box_dims %[[ARG0]], %[[C0]] : (!fir.box<!fir.array<?xi32>>, index) -> (index, index, index)
-! HLFIR: %[[SHAPE:.*]] = fir.shape %[[BOX_DIMS]]#1 : (index) -> !fir.shape<1>
-! HLFIR: %[[TEMP:.*]] = fir.allocmem !fir.array<?xi32>, %[[BOX_DIMS]]#1 {bindc_name = ".tmp", uniq_name = ""}
-! HLFIR: %[[DECLARE:.*]]:2 = hlfir.declare %[[TEMP]](%[[SHAPE]]) {uniq_name = ".tmp"} : (!fir.heap<!fir.array<?xi32>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xi32>>, !fir.heap<!fir.array<?xi32>>)
-! HLFIR: hlfir.assign %[[INIT_VALUE]] to %[[DECLARE]]#0 : i32, !fir.box<!fir.array<?xi32>>
-! HLFIR: acc.yield %[[DECLARE]]#0 : !fir.box<!fir.array<?xi32>>
+! CHECK: %[[INIT_VALUE:.*]] = arith.constant 0 : i32
+! CHECK: %[[C0:.*]] = arith.constant 0 : index
+! CHECK: %[[BOX_DIMS:.*]]:3 = fir.box_dims %[[ARG0]], %[[C0]] : (!fir.box<!fir.array<?xi32>>, index) -> (index, index, index)
+! CHECK: %[[SHAPE:.*]] = fir.shape %[[BOX_DIMS]]#1 : (index) -> !fir.shape<1>
+! CHECK: %[[TEMP:.*]] = fir.allocmem !fir.array<?xi32>, %[[BOX_DIMS]]#1 {bindc_name = ".tmp", uniq_name = ""}
+! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[TEMP]](%[[SHAPE]]) {uniq_name = ".tmp"} : (!fir.heap<!fir.array<?xi32>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xi32>>, !fir.heap<!fir.array<?xi32>>)
+! CHECK: hlfir.assign %[[INIT_VALUE]] to %[[DECLARE]]#0 : i32, !fir.box<!fir.array<?xi32>>
+! CHECK: acc.yield %[[DECLARE]]#0 : !fir.box<!fir.array<?xi32>>
! CHECK: } combiner {
! CHECK: ^bb0(%[[V1:.*]]: !fir.box<!fir.array<?xi32>>, %[[V2:.*]]: !fir.box<!fir.array<?xi32>>
-! HLFIR: %[[LEFT:.*]] = hlfir.designate %[[ARG0]] (%{{.*}}:%{{.*}}:%{{.*}}) shape %{{.*}} : (!fir.box<!fir.array<?xi32>>, index, index, index, !fir.shape<1>) -> !fir.box<!fir.array<?xi32>>
-! HLFIR: %[[RIGHT:.*]] = hlfir.designate %[[ARG1]] (%{{.*}}:%{{.*}}:%{{.*}}) shape %{{.*}} : (!fir.box<!fir.array<?xi32>>, index, index, index, !fir.shape<1>) -> !fir.box<!fir.array<?xi32>>
-! HLFIR: %[[ELEMENTAL:.*]] = hlfir.elemental %{{.*}} unordered : (!fir.shape<1>) -> !hlfir.expr<?xi32> {
-! HLFIR: ^bb0(%{{.*}}: index):
-! HLFIR: %[[DES_V1:.*]] = hlfir.designate %[[LEFT]] (%{{.*}}) : (!fir.box<!fir.array<?xi32>>, index) -> !fir.ref<i32>
-! HLFIR: %[[DES_V2:.*]] = hlfir.designate %[[RIGHT]] (%{{.*}}) : (!fir.box<!fir.array<?xi32>>, index) -> !fir.ref<i32>
-! HLFIR: %[[LOAD_V1:.*]] = fir.load %[[DES_V1]] : !fir.ref<i32>
-! HLFIR: %[[LOAD_V2:.*]] = fir.load %[[DES_V2]] : !fir.ref<i32>
-! HLFIR: %[[COMBINED:.*]] = arith.addi %[[LOAD_V1]], %[[LOAD_V2]] : i32
-! HLFIR: hlfir.yield_element %[[COMBINED]] : i32
-! HLFIR: }
-! HLFIR: hlfir.assign %[[ELEMENTAL]] to %[[V1]] : !hlfir.expr<?xi32>, !fir.box<!fir.array<?xi32>>
+! CHECK: %[[LEFT:.*]] = hlfir.designate %[[ARG0]] (%{{.*}}:%{{.*}}:%{{.*}}) shape %{{.*}} : (!fir.box<!fir.array<?xi32>>, index, index, index, !fir.shape<1>) -> !fir.box<!fir.array<?xi32>>
+! CHECK: %[[RIGHT:.*]] = hlfir.designate %[[ARG1]] (%{{.*}}:%{{.*}}:%{{.*}}) shape %{{.*}} : (!fir.box<!fir.array<?xi32>>, index, index, index, !fir.shape<1>) -> !fir.box<!fir.array<?xi32>>
+! CHECK: %[[ELEMENTAL:.*]] = hlfir.elemental %{{.*}} unordered : (!fir.shape<1>) -> !hlfir.expr<?xi32> {
+! CHECK: ^bb0(%{{.*}}: index):
+! CHECK: %[[DES_V1:.*]] = hlfir.designate %[[LEFT]] (%{{.*}}) : (!fir.box<!fir.array<?xi32>>, index) -> !fir.ref<i32>
+! CHECK: %[[DES_V2:.*]] = hlfir.designate %[[RIGHT]] (%{{.*}}) : (!fir.box<!fir.array<?xi32>>, index) -> !fir.ref<i32>
+! CHECK: %[[LOAD_V1:.*]] = fir.load %[[DES_V1]] : !fir.ref<i32>
+! CHECK: %[[LOAD_V2:.*]] = fir.load %[[DES_V2]] : !fir.ref<i32>
+! CHECK: %[[COMBINED:.*]] = arith.addi %[[LOAD_V1]], %[[LOAD_V2]] : i32
+! CHECK: hlfir.yield_element %[[COMBINED]] : i32
+! CHECK: }
+! CHECK: hlfir.assign %[[ELEMENTAL]] to %[[V1]] : !hlfir.expr<?xi32>, !fir.box<!fir.array<?xi32>>
! CHECK: acc.yield %arg0 : !fir.box<!fir.array<?xi32>>
! CHECK: }
@@ -156,9 +155,9 @@
! CHECK: %[[UNDEF1:.*]] = fir.insert_value %[[UNDEF]], %[[REAL]], [0 : index] : (!fir.complex<4>, f32) -> !fir.complex<4>
! CHECK: %[[UNDEF2:.*]] = fir.insert_value %[[UNDEF1]], %[[IMAG]], [1 : index] : (!fir.complex<4>, f32) -> !fir.complex<4>
! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.complex<4>
-! HLFIR: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "acc.reduction.init"} : (!fir.ref<!fir.complex<4>>) -> (!fir.ref<!fir.complex<4>>, !fir.ref<!fir.complex<4>>)
-! HLFIR: fir.store %[[UNDEF2]] to %[[DECLARE]]#0 : !fir.ref<!fir.complex<4>>
-! HLFIR: acc.yield %[[DECLARE]]#0 : !fir.ref<!fir.complex<4>>
+! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "acc.reduction.init"} : (!fir.ref<!fir.complex<4>>) -> (!fir.ref<!fir.complex<4>>, !fir.ref<!fir.complex<4>>)
+! CHECK: fir.store %[[UNDEF2]] to %[[DECLARE]]#0 : !fir.ref<!fir.complex<4>>
+! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref<!fir.complex<4>>
! CHECK: } combiner {
! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref<!fir.complex<4>>, %[[ARG1:.*]]: !fir.ref<!fir.complex<4>>):
! CHECK: %[[LOAD0:.*]] = fir.load %[[ARG0]] : !fir.ref<!fir.complex<4>>
@@ -176,9 +175,9 @@
! CHECK: %[[UNDEF1:.*]] = fir.insert_value %[[UNDEF]], %[[REAL]], [0 : index] : (!fir.complex<4>, f32) -> !fir.complex<4>
! CHECK: %[[UNDEF2:.*]] = fir.insert_value %[[UNDEF1]], %[[IMAG]], [1 : index] : (!fir.complex<4>, f32) -> !fir.complex<4>
! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.complex<4>
-! HLFIR: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "acc.reduction.init"} : (!fir.ref<!fir.complex<4>>) -> (!fir.ref<!fir.complex<4>>, !fir.ref<!fir.complex<4>>)
-! HLFIR: fir.store %[[UNDEF2]] to %[[DECLARE]]#0 : !fir.ref<!fir.complex<4>>
-! HLFIR: acc.yield %[[DECLARE]]#0 : !fir.ref<!fir.complex<4>>
+! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "acc.reduction.init"} : (!fir.ref<!fir.complex<4>>) -> (!fir.ref<!fir.complex<4>>, !fir.ref<!fir.complex<4>>)
+! CHECK: fir.store %[[UNDEF2]] to %[[DECLARE]]#0 : !fir.ref<!fir.complex<4>>
+! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref<!fir.complex<4>>
! CHECK: } combiner {
! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref<!fir.complex<4>>, %[[ARG1:.*]]: !fir.ref<!fir.complex<4>>):
! CHECK: %[[LOAD0:.*]] = fir.load %[[ARG0]] : !fir.ref<!fir.complex<4>>
@@ -192,10 +191,10 @@
! CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.logical<4>>):
! CHECK: %[[CST:.*]] = arith.constant false
! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.logical<4>
-! HLFIR: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "acc.reduction.init"} : (!fir.ref<!fir.logical<4>>) -> (!fir.ref<!fir.logical<4>>, !fir.ref<!fir.logical<4>>)
+! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "acc.reduction.init"} : (!fir.ref<!fir.logical<4>>) -> (!fir.ref<!fir.logical<4>>, !fir.ref<!fir.logical<4>>)
! CHECK: %[[CONVERT:.*]] = fir.convert %[[CST]] : (i1) -> !fir.logical<4>
-! HLFIR: fir.store %[[CONVERT]] to %[[DECLARE]]#0 : !fir.ref<!fir.logical<4>>
-! HLFIR: acc.yield %[[DECLARE]]#0 : !fir.ref<!fir.logical<4>>
+! CHECK: fir.store %[[CONVERT]] to %[[DECLARE]]#0 : !fir.ref<!fir.logical<4>>
+! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref<!fir.logical<4>>
! CHECK: } combiner {
! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref<!fir.logical<4>>, %[[ARG1:.*]]: !fir.ref<!fir.logical<4>>):
! CHECK: %[[LOAD0:.*]] = fir.load %[[ARG0]] : !fir.ref<!fir.logical<4>>
@@ -212,10 +211,10 @@
! CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.logical<4>>):
! CHECK: %[[CST:.*]] = arith.constant true
! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.logical<4>
-! HLFIR: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "acc.reduction.init"} : (!fir.ref<!fir.logical<4>>) -> (!fir.ref<!fir.logical<4>>, !fir.ref<!fir.logical<4>>)
+! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "acc.reduction.init"} : (!fir.ref<!fir.logical<4>>) -> (!fir.ref<!fir.logical<4>>, !fir.ref<!fir.logical<4>>)
! CHECK: %[[CONVERT:.*]] = fir.convert %[[CST]] : (i1) -> !fir.logical<4>
-! HLFIR: fir.store %[[CONVERT]] to %[[DECLARE]]#0 : !fir.ref<!fir.logical<4>>
-! HLFIR: acc.yield %[[DECLARE]]#0 : !fir.ref<!fir.logical<4>>
+! CHECK: fir.store %[[CONVERT]] to %[[DECLARE]]#0 : !fir.ref<!fir.logical<4>>
+! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref<!fir.logical<4>>
! CHECK: } combiner {
! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref<!fir.logical<4>>, %[[ARG1:.*]]: !fir.ref<!fir.logical<4>>):
! CHECK: %[[LOAD0:.*]] = fir.load %[[ARG0]] : !fir.ref<!fir.logical<4>>
@@ -232,10 +231,10 @@
! CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.logical<4>>):
! CHECK: %[[CST:.*]] = arith.constant false
! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.logical<4>
-! HLFIR: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "acc.reduction.init"} : (!fir.ref<!fir.logical<4>>) -> (!fir.ref<!fir.logical<4>>, !fir.ref<!fir.logical<4>>)
+! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "acc.reduction.init"} : (!fir.ref<!fir.logical<4>>) -> (!fir.ref<!fir.logical<4>>, !fir.ref<!fir.logical<4>>)
! CHECK: %[[CONVERT:.*]] = fir.convert %[[CST]] : (i1) -> !fir.logical<4>
-! HLFIR: fir.store %[[CONVERT]] to %[[DECLARE]]#0 : !fir.ref<!fir.logical<4>>
-! HLFIR: acc.yield %[[DECLARE]]#0 : !fir.ref<!fir.logical<4>>
+! CHECK: fir.store %[[CONVERT]] to %[[DECLARE]]#0 : !fir.ref<!fir.logical<4>>
+! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref<!fir.logical<4>>
! CHECK: } combiner {
! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref<!fir.logical<4>>, %[[ARG1:.*]]: !fir.ref<!fir.logical<4>>):
! CHECK: %[[LOAD0:.*]] = fir.load %[[ARG0]] : !fir.ref<!fir.logical<4>>
@@ -252,10 +251,10 @@
! CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.logical<4>>):
! CHECK: %[[CST:.*]] = arith.constant true
! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.logical<4>
-! HLFIR: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "acc.reduction.init"} : (!fir.ref<!fir.logical<4>>) -> (!fir.ref<!fir.logical<4>>, !fir.ref<!fir.logical<4>>)
+! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "acc.reduction.init"} : (!fir.ref<!fir.logical<4>>) -> (!fir.ref<!fir.logical<4>>, !fir.ref<!fir.logical<4>>)
! CHECK: %[[CONVERT:.*]] = fir.convert %[[CST]] : (i1) -> !fir.logical<4>
-! HLFIR: fir.store %[[CONVERT]] to %[[DECLARE]]#0 : !fir.ref<!fir.logical<4>>
-! HLFIR: acc.yield %[[DECLARE]]#0 : !fir.ref<!fir.logical<4>>
+! CHECK: fir.store %[[CONVERT]] to %[[DECLARE]]#0 : !fir.ref<!fir.logical<4>>
+! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref<!fir.logical<4>>
! CHECK: } combiner {
! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref<!fir.logical<4>>, %[[ARG1:.*]]: !fir.ref<!fir.logical<4>>):
! CHECK: %[[LOAD0:.*]] = fir.load %[[ARG0]] : !fir.ref<!fir.logical<4>>
@@ -272,9 +271,9 @@
! CHECK: ^bb0(%{{.*}}: !fir.ref<i32>):
! CHECK: %[[CST:.*]] = arith.constant 0 : i32
! CHECK: %[[ALLOCA:.*]] = fir.alloca i32
-! HLFIR: %[[DECLARE]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "acc.reduction.init"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
-! HLFIR: fir.store %[[CST]] to %[[DECLARE]]#0 : !fir.ref<i32>
-! HLFIR: acc.yield %[[DECLARE]]#0 : !fir.ref<i32>
+! CHECK: %[[DECLARE]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "acc.reduction.init"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK: fir.store %[[CST]] to %[[DECLARE]]#0 : !fir.ref<i32>
+! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref<i32>
! CHECK: } combiner {
! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref<i32>, %[[ARG1:.*]]: !fir.ref<i32>):
! CHECK: %[[LOAD0:.*]] = fir.load %[[ARG0]] : !fir.ref<i32>
@@ -288,9 +287,9 @@
! CHECK: ^bb0(%{{.*}}: !fir.ref<i32>):
! CHECK: %[[CST:.*]] = arith.constant 0 : i32
! CHECK: %[[ALLOCA:.*]] = fir.alloca i32
-! HLFIR: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "acc.reduction.init"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
-! HLFIR: fir.store %[[CST]] to %[[DECLARE:.*]]#0 : !fir.ref<i32>
-! HLFIR: acc.yield %[[DECLARE:.*]]#0 : !fir.ref<i32>
+! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "acc.reduction.init"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK: fir.store %[[CST]] to %[[DECLARE:.*]]#0 : !fir.ref<i32>
+! CHECK: acc.yield %[[DECLARE:.*]]#0 : !fir.ref<i32>
! CHECK: } combiner {
! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref<i32>, %[[ARG1:.*]]: !fir.ref<i32>):
! CHECK: %[[LOAD0:.*]] = fir.load %[[ARG0]] : !fir.ref<i32>
@@ -304,9 +303,9 @@
! CHECK: ^bb0(%{{.*}}: !fir.ref<i32>):
! CHECK: %[[CST:.*]] = arith.constant -1 : i32
! CHECK: %[[ALLOCA:.*]] = fir.alloca i32
-! HLFIR: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "acc.reduction.init"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
-! HLFIR: fir.store %[[CST]] to %[[DECLARE]]#0 : !fir.ref<i32>
-! HLFIR: acc.yield %[[DECLARE]]#0 : !fir.ref<i32>
+! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "acc.reduction.init"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK: fir.store %[[CST]] to %[[DECLARE]]#0 : !fir.ref<i32>
+! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref<i32>
! CHECK: } combiner {
! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref<i32>, %[[ARG1:.*]]: !fir.ref<i32>):
! CHECK: %[[LOAD0:.*]] = fir.load %[[ARG0]] : !fir.ref<i32>
@@ -319,17 +318,17 @@
! CHECK-LABEL: acc.reduction.recipe @reduction_max_section_ext100_ref_100xf32 : !fir.ref<!fir.array<100xf32>> reduction_operator <max> init {
! CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.array<100xf32>>):
! CHECK: %[[INIT:.*]] = arith.constant -1.401300e-45 : f32
-! HLFIR: %[[SHAPE:.*]] = fir.shape %{{.*}} : (index) -> !fir.shape<1>
+! CHECK: %[[SHAPE:.*]] = fir.shape %{{.*}} : (index) -> !fir.shape<1>
! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<100xf32>
-! HLFIR: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]](%[[SHAPE]]) {uniq_name = "acc.reduction.init"} : (!fir.ref<!fir.array<100xf32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<100xf32>>, !fir.ref<!fir.array<100xf32>>)
+! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]](%[[SHAPE]]) {uniq_name = "acc.reduction.init"} : (!fir.ref<!fir.array<100xf32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<100xf32>>, !fir.ref<!fir.array<100xf32>>)
! CHECK: %[[LB:.*]] = arith.constant 0 : index
! CHECK: %[[UB:.*]] = arith.constant 99 : index
! CHECK: %[[STEP:.*]] = arith.constant 1 : index
! CHECK: fir.do_loop %[[IV:.*]] = %[[LB]] to %[[UB]] step %[[STEP]] {
-! HLFIR: %[[COORD:.*]] = fir.coordinate_of %[[DECLARE]]#0, %[[IV]] : (!fir.ref<!fir.array<100xf32>>, index) -> !fir.ref<f32>
-! HLFIR: fir.store %[[INIT]] to %[[COORD]] : !fir.ref<f32>
+! CHECK: %[[COORD:.*]] = fir.coordinate_of %[[DECLARE]]#0, %[[IV]] : (!fir.ref<!fir.array<100xf32>>, index) -> !fir.ref<f32>
+! CHECK: fir.store %[[INIT]] to %[[COORD]] : !fir.ref<f32>
! CHECK: }
-! HLFIR: acc.yield %[[DECLARE]]#0 : !fir.ref<!fir.array<100xf32>>
+! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref<!fir.array<100xf32>>
! CHECK: } combiner {
! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref<!fir.array<100xf32>>, %[[ARG1:.*]]: !fir.ref<!fir.array<100xf32>>):
! CHECK: %[[LB0:.*]] = arith.constant 0 : index
@@ -351,9 +350,9 @@
! CHECK: ^bb0(%{{.*}}: !fir.ref<f32>):
! CHECK: %[[INIT:.*]] = arith.constant -1.401300e-45 : f32
! CHECK: %[[ALLOCA:.*]] = fir.alloca f32
-! HLFIR: %[[DECLARE:.*]]:2 = hlfir.declare %0 {uniq_name = "acc.reduction.init"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
-! HLFIR: fir.store %[[INIT]] to %[[DECLARE]]#0 : !fir.ref<f32>
-! HLFIR: acc.yield %[[DECLARE]]#0 : !fir.ref<f32>
+! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %0 {uniq_name = "acc.reduction.init"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
+! CHECK: fir.store %[[INIT]] to %[[DECLARE]]#0 : !fir.ref<f32>
+! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref<f32>
! CHECK: } combiner {
! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref<f32>, %[[ARG1:.*]]: !fir.ref<f32>):
! CHECK: %[[LOAD0:.*]] = fir.load %[[ARG0]] : !fir.ref<f32>
@@ -367,10 +366,10 @@
! CHECK-LABEL: acc.reduction.recipe @reduction_max_section_ext100xext10_ref_100x10xi32 : !fir.ref<!fir.array<100x10xi32>> reduction_operator <max> init {
! CHECK: ^bb0(%arg0: !fir.ref<!fir.array<100x10xi32>>):
! CHECK: %[[INIT:.*]] = arith.constant -2147483648 : i32
-! HLFIR: %[[SHAPE:.*]] = fir.shape %{{.*}}, %{{.*}} : (index, index) -> !fir.shape<2>
+! CHECK: %[[SHAPE:.*]] = fir.shape %{{.*}}, %{{.*}} : (index, index) -> !fir.shape<2>
! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<100x10xi32>
-! HLFIR: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]](%[[SHAPE]]) {uniq_name = "acc.reduction.init"} : (!fir.ref<!fir.array<100x10xi32>>, !fir.shape<2>) -> (!fir.ref<!fir.array<100x10xi32>>, !fir.ref<!fir.array<100x10xi32>>)
-! HLFIR: acc.yield %[[DECLARE]]#0 : !fir.ref<!fir.array<100x10xi32>>
+! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]](%[[SHAPE]]) {uniq_name = "acc.reduction.init"} : (!fir.ref<!fir.array<100x10xi32>>, !fir.shape<2>) -> (!fir.ref<!fir.array<100x10xi32>>, !fir.ref<!fir.array<100x10xi32>>)
+! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref<!fir.array<100x10xi32>>
! CHECK: } combiner {
! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref<!fir.array<100x10xi32>>, %[[ARG1:.*]]: !fir.ref<!fir.array<100x10xi32>>):
! CHECK: %[[LB0:.*]] = arith.constant 0 : index
@@ -397,9 +396,9 @@
! CHECK: ^bb0(%arg0: !fir.ref<i32>):
! CHECK: %[[INIT:.*]] = arith.constant -2147483648 : i32
! CHECK: %[[ALLOCA:.*]] = fir.alloca i32
-! HLFIR: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "acc.reduction.init"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
-! HLFIR: fir.store %[[INIT]] to %[[DECLARE]]#0 : !fir.ref<i32>
-! HLFIR: acc.yield %[[DECLARE]]#0 : !fir.ref<i32>
+! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "acc.reduction.init"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK: fir.store %[[INIT]] to %[[DECLARE]]#0 : !fir.ref<i32>
+! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref<i32>
! CHECK: } combiner {
! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref<i32>, %[[ARG1:.*]]: !fir.ref<i32>):
! CHECK: %[[LOAD0:.*]] = fir.load %[[ARG0]] : !fir.ref<i32>
@@ -413,10 +412,10 @@
! CHECK-LABEL: acc.reduction.recipe @reduction_min_section_ext100xext10_ref_100x10xf32 : !fir.ref<!fir.array<100x10xf32>> reduction_operator <min> init {
! CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.array<100x10xf32>>):
! CHECK: %[[INIT:.*]] = arith.constant 3.40282347E+38 : f32
-! HLFIR: %[[SHAPE:.*]] = fir.shape %{{.*}}, %{{.*}} : (index, index) -> !fir.shape<2>
+! CHECK: %[[SHAPE:.*]] = fir.shape %{{.*}}, %{{.*}} : (index, index) -> !fir.shape<2>
! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<100x10xf32>
-! HLFIR: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]](%[[SHAPE]]) {uniq_name = "acc.reduction.init"} : (!fir.ref<!fir.array<100x10xf32>>, !fir.shape<2>) -> (!fir.ref<!fir.array<100x10xf32>>, !fir.ref<!fir.array<100x10xf32>>)
-! HLFIR: acc.yield %[[DECLARE]]#0 : !fir.ref<!fir.array<100x10xf32>>
+! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]](%[[SHAPE]]) {uniq_name = "acc.reduction.init"} : (!fir.ref<!fir.array<100x10xf32>>, !fir.shape<2>) -> (!fir.ref<!fir.array<100x10xf32>>, !fir.ref<!fir.array<100x10xf32>>)
+! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref<!fir.array<100x10xf32>>
! CHECK: } combiner {
! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref<!fir.array<100x10xf32>>, %[[ARG1:.*]]: !fir.ref<!fir.array<100x10xf32>>):
! CHECK: %[[LB0:.*]] = arith.constant 0 : index
@@ -443,9 +442,9 @@
! CHECK: ^bb0(%{{.*}}: !fir.ref<f32>):
! CHECK: %[[INIT:.*]] = arith.constant 3.40282347E+38 : f32
! CHECK: %[[ALLOCA:.*]] = fir.alloca f32
-! HLFIR: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "acc.reduction.init"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
-! HLFIR: fir.store %[[INIT]] to %[[DECLARE]]#0 : !fir.ref<f32>
-! HLFIR: acc.yield %[[DECLARE]]#0 : !fir.ref<f32>
+! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "acc.reduction.init"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
+! CHECK: fir.store %[[INIT]] to %[[DECLARE]]#0 : !fir.ref<f32>
+! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref<f32>
! CHECK: } combiner {
! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref<f32>, %[[ARG1:.*]]: !fir.ref<f32>):
! CHECK: %[[LOAD0:.*]] = fir.load %[[ARG0]] : !fir.ref<f32>
@@ -459,10 +458,10 @@
! CHECK-LABEL: acc.reduction.recipe @reduction_min_section_ext100_ref_100xi32 : !fir.ref<!fir.array<100xi32>> reduction_operator <min> init {
! CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.array<100xi32>>):
! CHECK: %[[INIT:.*]] = arith.constant 2147483647 : i32
-! HLFIR: %[[SHAPE:.*]] = fir.shape %{{.*}} : (index) -> !fir.shape<1>
+! CHECK: %[[SHAPE:.*]] = fir.shape %{{.*}} : (index) -> !fir.shape<1>
! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<100xi32>
-! HLFIR: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]](%[[SHAPE]]) {uniq_name = "acc.reduction.init"} : (!fir.ref<!fir.array<100xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<100xi32>>, !fir.ref<!fir.array<100xi32>>)
-! HLFIR: acc.yield %[[DECLARE]]#0 : !fir.ref<!fir.array<100xi32>>
+! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]](%[[SHAPE]]) {uniq_name = "acc.reduction.init"} : (!fir.ref<!fir.array<100xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<100xi32>>, !fir.ref<!fir.array<100xi32>>)
+! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref<!fir.array<100xi32>>
! CHECK: } combiner {
! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref<!fir.array<100xi32>>, %[[ARG1:.*]]: !fir.ref<!fir.array<100xi32>>):
! CHECK: %[[LB0:.*]] = arith.constant 0 : index
@@ -484,9 +483,9 @@
! CHECK: ^bb0(%{{.*}}: !fir.ref<i32>):
! CHECK: %[[INIT:.*]] = arith.constant 2147483647 : i32
! CHECK: %[[ALLOCA:.*]] = fir.alloca i32
-! HLFIR: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "acc.reduction.init"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
-! HLFIR: fir.store %[[INIT]] to %[[DECLARE]]#0 : !fir.ref<i32>
-! HLFIR: acc.yield %[[DECLARE]]#0 : !fir.ref<i32>
+! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "acc.reduction.init"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK: fir.store %[[INIT]] to %[[DECLARE]]#0 : !fir.ref<i32>
+! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref<i32>
! CHECK: } combiner {
! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref<i32>, %[[ARG1:.*]]: !fir.ref<i32>):
! CHECK: %[[LOAD0:.*]] = fir.load %[[ARG0]] : !fir.ref<i32>
@@ -501,9 +500,9 @@
! CHECK: ^bb0(%{{.*}}: !fir.ref<f32>):
! CHECK: %[[INIT:.*]] = arith.constant 1.000000e+00 : f32
! CHECK: %[[ALLOCA:.*]] = fir.alloca f32
-! HLFIR: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "acc.reduction.init"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
-! HLFIR: fir.store %[[INIT]] to %[[DECLARE]]#0 : !fir.ref<f32>
-! HLFIR: acc.yield %[[DECLARE]]#0 : !fir.ref<f32>
+! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "acc.reduction.init"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
+! CHECK: fir.store %[[INIT]] to %[[DECLARE]]#0 : !fir.ref<f32>
+! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref<f32>
! CHECK: } combiner {
! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref<f32>, %[[ARG1:.*]]: !fir.ref<f32>):
! CHECK: %[[LOAD0:.*]] = fir.load %[[ARG0]] : !fir.ref<f32>
@@ -516,10 +515,10 @@
! CHECK-LABEL: acc.reduction.recipe @reduction_mul_section_ext100_ref_100xi32 : !fir.ref<!fir.array<100xi32>> reduction_operator <mul> init {
! CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.array<100xi32>>):
! CHECK: %[[INIT:.*]] = arith.constant 1 : i32
-! HLFIR: %[[SHAPE:.*]] = fir.shape %{{.*}} : (index) -> !fir.shape<1>
+! CHECK: %[[SHAPE:.*]] = fir.shape %{{.*}} : (index) -> !fir.shape<1>
! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<100xi32>
-! HLFIR: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]](%[[SHAPE]]) {uniq_name = "acc.reduction.init"} : (!fir.ref<!fir.array<100xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<100xi32>>, !fir.ref<!fir.array<100xi32>>)
-! HLFIR: acc.yield %[[DECLARE]]#0 : !fir.ref<!fir.array<100xi32>>
+! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]](%[[SHAPE]]) {uniq_name = "acc.reduction.init"} : (!fir.ref<!fir.array<100xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<100xi32>>, !fir.ref<!fir.array<100xi32>>)
+! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref<!fir.array<100xi32>>
! CHECK: } combiner {
! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref<!fir.array<100xi32>>, %[[ARG1:.*]]: !fir.ref<!fir.array<100xi32>>):
! CHECK: %[[LB:.*]] = arith.constant 0 : index
@@ -540,9 +539,9 @@
! CHECK: ^bb0(%{{.*}}: !fir.ref<i32>):
! CHECK: %[[INIT:.*]] = arith.constant 1 : i32
! CHECK: %[[ALLOCA:.*]] = fir.alloca i32
-! HLFIR: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "acc.reduction.init"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
-! HLFIR: fir.store %[[INIT]] to %[[DECLARE]]#0 : !fir.ref<i32>
-! HLFIR: acc.yield %[[DECLARE]]#0 : !fir.ref<i32>
+! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "acc.reduction.init"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK: fir.store %[[INIT]] to %[[DECLARE]]#0 : !fir.ref<i32>
+! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref<i32>
! CHECK: } combiner {
! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref<i32>, %[[ARG1:.*]]: !fir.ref<i32>):
! CHECK: %[[LOAD0:.*]] = fir.load %[[ARG0]] : !fir.ref<i32>
@@ -555,10 +554,10 @@
! CHECK-LABEL: acc.reduction.recipe @reduction_add_section_ext100_ref_100xf32 : !fir.ref<!fir.array<100xf32>> reduction_operator <add> init {
! CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.array<100xf32>>):
! CHECK: %[[INIT:.*]] = arith.constant 0.000000e+00 : f32
-! HLFIR: %[[SHAPE:.*]] = fir.shape %{{.*}} : (index) -> !fir.shape<1>
+! CHECK: %[[SHAPE:.*]] = fir.shape %{{.*}} : (index) -> !fir.shape<1>
! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<100xf32>
-! HLFIR: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]](%[[SHAPE]]) {uniq_name = "acc.reduction.init"} : (!fir.ref<!fir.array<100xf32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<100xf32>>, !fir.ref<!fir.array<100xf32>>)
-! HLFIR: acc.yield %[[DECLARE]]#0 : !fir.ref<!fir.array<100xf32>>
+! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]](%[[SHAPE]]) {uniq_name = "acc.reduction.init"} : (!fir.ref<!fir.array<100xf32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<100xf32>>, !fir.ref<!fir.array<100xf32>>)
+! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref<!fir.array<100xf32>>
! CHECK: } combiner {
! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref<!fir.array<100xf32>>, %[[ARG1:.*]]: !fir.ref<!fir.array<100xf32>>):
! CHECK: %[[LB:.*]] = arith.constant 0 : index
@@ -579,9 +578,9 @@
! CHECK: ^bb0(%{{.*}}: !fir.ref<f32>):
! CHECK: %[[INIT:.*]] = arith.constant 0.000000e+00 : f32
! CHECK: %[[ALLOCA:.*]] = fir.alloca f32
-! HLFIR: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "acc.reduction.init"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
-! HLFIR: fir.store %[[INIT]] to %[[DECLARE]]#0 : !fir.ref<f32>
-! HLFIR: acc.yield %[[DECLARE]]#0 : !fir.ref<f32>
+! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "acc.reduction.init"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
+! CHECK: fir.store %[[INIT]] to %[[DECLARE]]#0 : !fir.ref<f32>
+! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref<f32>
! CHECK: } combiner {
! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref<f32>, %[[ARG1:.*]]: !fir.ref<f32>):
! CHECK: %[[LOAD0:.*]] = fir.load %[[ARG0]] : !fir.ref<f32>
@@ -594,10 +593,10 @@
! CHECK-LABEL: acc.reduction.recipe @reduction_add_section_ext100xext10xext2_ref_100x10x2xi32 : !fir.ref<!fir.array<100x10x2xi32>> reduction_operator <add> init {
! CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.array<100x10x2xi32>>):
! CHECK: %[[INIT:.*]] = arith.constant 0 : i32
-! HLFIR: %[[SHAPE:.*]] = fir.shape %{{.*}}, %{{.*}}, %{{.*}} : (index, index, index) -> !fir.shape<3>
+! CHECK: %[[SHAPE:.*]] = fir.shape %{{.*}}, %{{.*}}, %{{.*}} : (index, index, index) -> !fir.shape<3>
! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<100x10x2xi32>
-! HLFIR: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]](%[[SHAPE]]) {uniq_name = "acc.reduction.init"} : (!fir.ref<!fir.array<100x10x2xi32>>, !fir.shape<3>) -> (!fir.ref<!fir.array<100x10x2xi32>>, !fir.ref<!fir.array<100x10x2xi32>>)
-! HLFIR: acc.yield %[[DECLARE]]#0 : !fir.ref<!fir.array<100x10x2xi32>>
+! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]](%[[SHAPE]]) {uniq_name = "acc.reduction.init"} : (!fir.ref<!fir.array<100x10x2xi32>>, !fir.shape<3>) -> (!fir.ref<!fir.array<100x10x2xi32>>, !fir.ref<!fir.array<100x10x2xi32>>)
+! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref<!fir.array<100x10x2xi32>>
! CHECK: } combiner {
! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref<!fir.array<100x10x2xi32>>, %[[ARG1:.*]]: !fir.ref<!fir.array<100x10x2xi32>>):
! CHECK: %[[LB0:.*]] = arith.constant 0 : index
@@ -627,10 +626,10 @@
! CHECK-LABEL: acc.reduction.recipe @reduction_add_section_ext100xext10_ref_100x10xi32 : !fir.ref<!fir.array<100x10xi32>> reduction_operator <add> init {
! CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.array<100x10xi32>>):
! CHECK: %[[INIT:.*]] = arith.constant 0 : i32
-! HLFIR: %[[SHAPE:.*]] = fir.shape %{{.*}}, %{{.*}} : (index, index) -> !fir.shape<2>
+! CHECK: %[[SHAPE:.*]] = fir.shape %{{.*}}, %{{.*}} : (index, index) -> !fir.shape<2>
! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<100x10xi32>
-! HLFIR: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]](%[[SHAPE]]) {uniq_name = "acc.reduction.init"} : (!fir.ref<!fir.array<100x10xi32>>, !fir.shape<2>) -> (!fir.ref<!fir.array<100x10xi32>>, !fir.ref<!fir.array<100x10xi32>>)
-! HLFIR: acc.yield %[[DECLARE]]#0 : !fir.ref<!fir.array<100x10xi32>>
+! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]](%[[SHAPE]]) {uniq_name = "acc.reduction.init"} : (!fir.ref<!fir.array<100x10xi32>>, !fir.shape<2>) -> (!fir.ref<!fir.array<100x10xi32>>, !fir.ref<!fir.array<100x10xi32>>)
+! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref<!fir.array<100x10xi32>>
! CHECK: } combiner {
! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref<!fir.array<100x10xi32>>, %[[ARG1:.*]]: !fir.ref<!fir.array<100x10xi32>>):
! CHECK: %[[LB0:.*]] = arith.constant 0 : index
@@ -655,9 +654,9 @@
! CHECK-LABEL: acc.reduction.recipe @reduction_add_section_ext100_ref_100xi32 : !fir.ref<!fir.array<100xi32>> reduction_operator <add> init {
! CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.array<100xi32>>):
! CHECK: %[[INIT:.*]] = arith.constant 0 : i32
-! HLFIR: %[[SHAPE:.*]] = fir.shape %{{.*}} : (index) -> !fir.shape<1>
+! CHECK: %[[SHAPE:.*]] = fir.shape %{{.*}} : (index) -> !fir.shape<1>
! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<100xi32>
-! HLFIR: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]](%[[SHAPE]]) {uniq_name = "acc.reduction.init"} : (!fir.ref<!fir.array<100xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<100xi32>>, !fir.ref<!fir.array<100xi32>>)
+! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]](%[[SHAPE]]) {uniq_name = "acc.reduction.init"} : (!fir.ref<!fir.array<100xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<100xi32>>, !fir.ref<!fir.array<100xi32>>)
! HFLIR: acc.yield %[[DECLARE]]#0 : !fir.ref<!fir.array<100xi32>>
! CHECK: } combiner {
! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref<!fir.array<100xi32>>, %[[ARG1:.*]]: !fir.ref<!fir.array<100xi32>>):
@@ -679,9 +678,9 @@
! CHECK: ^bb0(%{{.*}}: !fir.ref<i32>):
! CHECK: %[[INIT:.*]] = arith.constant 0 : i32
! CHECK: %[[ALLOCA:.*]] = fir.alloca i32
-! HLFIR: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "acc.reduction.init"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
-! HLFIR: fir.store %[[INIT]] to %[[DECLARE]]#0 : !fir.ref<i32>
-! HLFIR: acc.yield %[[DECLARE]]#0 : !fir.ref<i32>
+! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "acc.reduction.init"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK: fir.store %[[INIT]] to %[[DECLARE]]#0 : !fir.ref<i32>
+! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref<i32>
! CHECK: } combiner {
! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref<i32>, %[[ARG1:.*]]: !fir.ref<i32>):
! CHECK: %[[LOAD0:.*]] = fir.load %[[ARG0]] : !fir.ref<i32>
@@ -703,9 +702,8 @@ end subroutine
! CHECK-LABEL: func.func @_QPacc_reduction_add_int(
! CHECK-SAME: %{{.*}}: !fir.ref<!fir.array<100xi32>> {fir.bindc_name = "a"}, %[[B:.*]]: !fir.ref<i32> {fir.bindc_name = "b"})
-! HLFIR: %[[DECLB:.*]]:2 = hlfir.declare %[[B]]
-! FIR: %[[RED_B:.*]] = acc.reduction varPtr(%[[B]] : !fir.ref<i32>) -> !fir.ref<i32> {name = "b"}
-! HLFIR: %[[RED_B:.*]] = acc.reduction varPtr(%[[DECLB]]#1 : !fir.ref<i32>) -> !fir.ref<i32> {name = "b"}
+! CHECK: %[[DECLB:.*]]:2 = hlfir.declare %[[B]]
+! CHECK: %[[RED_B:.*]] = acc.reduction varPtr(%[[DECLB]]#1 : !fir.ref<i32>) -> !fir.ref<i32> {name = "b"}
! CHECK: acc.loop reduction(@reduction_add_ref_i32 -> %[[RED_B]] : !fir.ref<i32>)
subroutine acc_reduction_add_int_array_1d(a, b)
@@ -720,9 +718,8 @@ end subroutine
! CHECK-LABEL: func.func @_QPacc_reduction_add_int_array_1d(
! CHECK-SAME: %{{.*}}: !fir.ref<!fir.array<100xi32>> {fir.bindc_name = "a"}, %[[B:.*]]: !fir.ref<!fir.array<100xi32>> {fir.bindc_name = "b"})
-! HLFIR: %[[DECLB:.*]]:2 = hlfir.declare %[[B]]
-! FIR: %[[RED_B:.*]] = acc.reduction varPtr(%[[B]] : !fir.ref<!fir.array<100xi32>>) bounds(%{{.*}}) -> !fir.ref<!fir.array<100xi32>> {name = "b"}
-! HLFIR: %[[RED_B:.*]] = acc.reduction varPtr(%[[DECLB]]#1 : !fir.ref<!fir.array<100xi32>>) bounds(%{{.*}}) -> !fir.ref<!fir.array<100xi32>> {name = "b"}
+! CHECK: %[[DECLB:.*]]:2 = hlfir.declare %[[B]]
+! CHECK: %[[RED_B:.*]] = acc.reduction varPtr(%[[DECLB]]#1 : !fir.ref<!fir.array<100xi32>>) bounds(%{{.*}}) -> !fir.ref<!fir.array<100xi32>> {name = "b"}
! CHECK: acc.loop reduction(@reduction_add_section_ext100_ref_100xi32 -> %[[RED_B]] : !fir.ref<!fir.array<100xi32>>)
subroutine acc_reduction_add_int_array_2d(a, b)
@@ -739,9 +736,8 @@ end subroutine
! CHECK-LABEL: func.func @_QPacc_reduction_add_int_array_2d(
! CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.array<100x10xi32>> {fir.bindc_name = "a"}, %[[ARG1:.*]]: !fir.ref<!fir.array<100x10xi32>> {fir.bindc_name = "b"}) {
-! HLFIR: %[[DECLARG1:.*]]:2 = hlfir.declare %[[ARG1]]
-! FIR: %[[RED_ARG1:.*]] = acc.reduction varPtr(%[[ARG1]] : !fir.ref<!fir.array<100x10xi32>>) bounds(%{{.*}}, %{{.*}}) -> !fir.ref<!fir.array<100x10xi32>> {name = "b"}
-! HLFIR: %[[RED_ARG1:.*]] = acc.reduction varPtr(%[[DECLARG1]]#1 : !fir.ref<!fir.array<100x10xi32>>) bounds(%{{.*}}, %{{.*}}) -> !fir.ref<!fir.array<100x10xi32>> {name = "b"}
+! CHECK: %[[DECLARG1:.*]]:2 = hlfir.declare %[[ARG1]]
+! CHECK: %[[RED_ARG1:.*]] = acc.reduction varPtr(%[[DECLARG1]]#1 : !fir.ref<!fir.array<100x10xi32>>) bounds(%{{.*}}, %{{.*}}) -> !fir.ref<!fir.array<100x10xi32>> {name = "b"}
! CHECK: acc.loop reduction(@reduction_add_section_ext100xext10_ref_100x10xi32 -> %[[RED_ARG1]] : !fir.ref<!fir.array<100x10xi32>>) {
! CHECK: } attributes {collapse = [2], collapseDeviceType = [#acc.device_type<none>]}
@@ -761,9 +757,8 @@ end subroutine
! CHECK-LABEL: func.func @_QPacc_reduction_add_int_array_3d(
! CHECK-SAME: %{{.*}}: !fir.ref<!fir.array<100x10x2xi32>> {fir.bindc_name = "a"}, %[[ARG1:.*]]: !fir.ref<!fir.array<100x10x2xi32>> {fir.bindc_name = "b"})
-! HLFIR: %[[DECLARG1:.*]]:2 = hlfir.declare %[[ARG1]]
-! FIR: %[[RED_ARG1:.*]] = acc.reduction varPtr(%[[ARG1]] : !fir.ref<!fir.array<100x10x2xi32>>) bounds(%{{.*}}, %{{.*}}, %{{.*}}) -> !fir.ref<!fir.array<100x10x2xi32>> {name = "b"}
-! HLFIR: %[[RED_ARG1:.*]] = acc.reduction varPtr(%[[DECLARG1]]#1 : !fir.ref<!fir.array<100x10x2xi32>>) bounds(%{{.*}}, %{{.*}}, %{{.*}}) -> !fir.ref<!fir.array<100x10x2xi32>> {name = "b"}
+! CHECK: %[[DECLARG1:.*]]:2 = hlfir.declare %[[ARG1]]
+! CHECK: %[[RED_ARG1:.*]] = acc.reduction varPtr(%[[DECLARG1]]#1 : !fir.ref<!fir.array<100x10x2xi32>>) bounds(%{{.*}}, %{{.*}}, %{{.*}}) -> !fir.ref<!fir.array<100x10x2xi32>> {name = "b"}
! CHECK: acc.loop reduction(@reduction_add_section_ext100xext10xext2_ref_100x10x2xi32 -> %[[RED_ARG1]] : !fir.ref<!fir.array<100x10x2xi32>>)
! CHECK: } attributes {collapse = [3], collapseDeviceType = [#acc.device_type<none>]}
@@ -779,9 +774,8 @@ end subroutine
! CHECK-LABEL: func.func @_QPacc_reduction_add_float(
! CHECK-SAME: %{{.*}}: !fir.ref<!fir.array<100xf32>> {fir.bindc_name = "a"}, %[[B:.*]]: !fir.ref<f32> {fir.bindc_name = "b"})
-! HLFIR: %[[DECLB:.*]]:2 = hlfir.declare %[[B]]
-! FIR: %[[RED_B:.*]] = acc.reduction varPtr(%[[B]] : !fir.ref<f32>) -> !fir.ref<f32> {name = "b"}
-! HLFIR: %[[RED_B:.*]] = acc.reduction varPtr(%[[DECLB]]#1 : !fir.ref<f32>) -> !fir.ref<f32> {name = "b"}
+! CHECK: %[[DECLB:.*]]:2 = hlfir.declare %[[B]]
+! CHECK: %[[RED_B:.*]] = acc.reduction varPtr(%[[DECLB]]#1 : !fir.ref<f32>) -> !fir.ref<f32> {name = "b"}
! CHECK: acc.loop reduction(@reduction_add_ref_f32 -> %[[RED_B]] : !fir.ref<f32>)
subroutine acc_reduction_add_float_array_1d(a, b)
@@ -796,9 +790,8 @@ end subroutine
! CHECK-LABEL: func.func @_QPacc_reduction_add_float_array_1d(
! CHECK-SAME: %{{.*}}: !fir.ref<!fir.array<100xf32>> {fir.bindc_name = "a"}, %[[B:.*]]: !fir.ref<!fir.array<100xf32>> {fir.bindc_name = "b"})
-! HLFIR: %[[DECLB:.*]]:2 = hlfir.declare %[[B]]
-! FIR: %[[RED_B:.*]] = acc.reduction varPtr(%[[B]] : !fir.ref<!fir.array<100xf32>>) bounds(%{{.*}}) -> !fir.ref<!fir.array<100xf32>> {name = "b"}
-! HLFIR: %[[RED_B:.*]] = acc.reduction varPtr(%[[DECLB]]#1 : !fir.ref<!fir.array<100xf32>>) bounds(%{{.*}}) -> !fir.ref<!fir.array<100xf32>> {name = "b"}
+! CHECK: %[[DECLB:.*]]:2 = hlfir.declare %[[B]]
+! CHECK: %[[RED_B:.*]] = acc.reduction varPtr(%[[DECLB]]#1 : !fir.ref<!fir.array<100xf32>>) bounds(%{{.*}}) -> !fir.ref<!fir.array<100xf32>> {name = "b"}
! CHECK: acc.loop reduction(@reduction_add_section_ext100_ref_100xf32 -> %[[RED_B]] : !fir.ref<!fir.array<100xf32>>)
subroutine acc_reduction_mul_int(a, b)
@@ -813,9 +806,8 @@ end subroutine
! CHECK-LABEL: func.func @_QPacc_reduction_mul_int(
! CHECK-SAME: %{{.*}}: !fir.ref<!fir.array<100xi32>> {fir.bindc_name = "a"}, %[[B:.*]]: !fir.ref<i32> {fir.bindc_name = "b"})
-! HLFIR: %[[DECLB:.*]]:2 = hlfir.declare %[[B]]
-! FIR: %[[RED_B:.*]] = acc.reduction varPtr(%[[B]] : !fir.ref<i32>) -> !fir.ref<i32> {name = "b"}
-! HLFIR: %[[RED_B:.*]] = acc.reduction varPtr(%[[DECLB]]#1 : !fir.ref<i32>) -> !fir.ref<i32> {name = "b"}
+! CHECK: %[[DECLB:.*]]:2 = hlfir.declare %[[B]]
+! CHECK: %[[RED_B:.*]] = acc.reduction varPtr(%[[DECLB]]#1 : !fir.ref<i32>) -> !fir.ref<i32> {name = "b"}
! CHECK: acc.loop reduction(@reduction_mul_ref_i32 -> %[[RED_B]] : !fir.ref<i32>)
subroutine acc_reduction_mul_int_array_1d(a, b)
@@ -830,9 +822,8 @@ end subroutine
! CHECK-LABEL: func.func @_QPacc_reduction_mul_int_array_1d(
! CHECK-SAME: %{{.*}}: !fir.ref<!fir.array<100xi32>> {fir.bindc_name = "a"}, %[[B:.*]]: !fir.ref<!fir.array<100xi32>> {fir.bindc_name = "b"})
-! HLFIR: %[[DECLB:.*]]:2 = hlfir.declare %[[B]]
-! FIR: %[[RED_B:.*]] = acc.reduction varPtr(%[[B]] : !fir.ref<!fir.array<100xi32>>) bounds(%{{.*}}) -> !fir.ref<!fir.array<100xi32>> {name = "b"}
-! HLFIR: %[[RED_B:.*]] = acc.reduction varPtr(%[[DECLB]]#1 : !fir.ref<!fir.array<100xi32>>) bounds(%{{.*}}) -> !fir.ref<!fir.array<100xi32>> {name = "b"}
+! CHECK: %[[DECLB:.*]]:2 = hlfir.declare %[[B]]
+! CHECK: %[[RED_B:.*]] = acc.reduction varPtr(%[[DECLB]]#1 : !fir.ref<!fir.array<100xi32>>) bounds(%{{.*}}) -> !fir.ref<!fir.array<100xi32>> {name = "b"}
! CHECK: acc.loop reduction(@reduction_mul_section_ext100_ref_100xi32 -> %[[RED_B]] : !fir.ref<!fir.array<100xi32>>)
subroutine acc_reduction_mul_float(a, b)
@@ -847,9 +838,8 @@ end subroutine
! CHECK-LABEL: func.func @_QPacc_reduction_mul_float(
! CHECK-SAME: %{{.*}}: !fir.ref<!fir.array<100xf32>> {fir.bindc_name = "a"}, %[[B:.*]]: !fir.ref<f32> {fir.bindc_name = "b"})
-! HLFIR: %[[DECLB:.*]]:2 = hlfir.declare %[[B]]
-! FIR: %[[RED_B:.*]] = acc.reduction varPtr(%[[B]] : !fir.ref<f32>) -> !fir.ref<f32> {name = "b"}
-! HLFIR: %[[RED_B:.*]] = acc.reduction varPtr(%[[DECLB]]#1 : !fir.ref<f32>) -> !fir.ref<f32> {name = "b"}
+! CHECK: %[[DECLB:.*]]:2 = hlfir.declare %[[B]]
+! CHECK: %[[RED_B:.*]] = acc.reduction varPtr(%[[DECLB]]#1 : !fir.ref<f32>) -> !fir.ref<f32> {name = "b"}
! CHECK: acc.loop reduction(@reduction_mul_ref_f32 -> %[[RED_B]] : !fir.ref<f32>)
subroutine acc_reduction_mul_float_array_1d(a, b)
@@ -864,9 +854,8 @@ end subroutine
! CHECK-LABEL: func.func @_QPacc_reduction_mul_float_array_1d(
! CHECK-SAME: %{{.*}}: !fir.ref<!fir.array<100xf32>> {fir.bindc_name = "a"}, %[[B:.*]]: !fir.ref<!fir.array<100xf32>> {fir.bindc_name = "b"})
-! HLFIR: %[[DECLB:.*]]:2 = hlfir.declare %[[B]]
-! FIR: %[[RED_B:.*]] = acc.reduction varPtr(%[[B]] : !fir.ref<!fir.array<100xf32>>) bounds(%2) -> !fir.ref<!fir.array<100xf32>> {name = "b"}
-! HLFIR: %[[RED_B:.*]] = acc.reduction varPtr(%[[DECLB]]#1 : !fir.ref<!fir.array<100xf32>>) bounds(%{{.*}}) -> !fir.ref<!fir.array<100xf32>> {name = "b"}
+! CHECK: %[[DECLB:.*]]:2 = hlfir.declare %[[B]]
+! CHECK: %[[RED_B:.*]] = acc.reduction varPtr(%[[DECLB]]#1 : !fir.ref<!fir.array<100xf32>>) bounds(%{{.*}}) -> !fir.ref<!fir.array<100xf32>> {name = "b"}
! CHECK: acc.loop reduction(@reduction_mul_section_ext100_ref_100xf32 -> %[[RED_B]] : !fir.ref<!fir.array<100xf32>>)
subroutine acc_reduction_min_int(a, b)
@@ -881,9 +870,8 @@ end subroutine
! CHECK-LABEL: func.func @_QPacc_reduction_min_int(
! CHECK-SAME: %{{.*}}: !fir.ref<!fir.array<100xi32>> {fir.bindc_name = "a"}, %[[B:.*]]: !fir.ref<i32> {fir.bindc_name = "b"})
-! HLFIR: %[[DECLB:.*]]:2 = hlfir.declare %[[B]]
-! FIR: %[[RED_B:.*]] = acc.reduction varPtr(%[[B]] : !fir.ref<i32>) -> !fir.ref<i32> {name = "b"}
-! HLFIR: %[[RED_B:.*]] = acc.reduction varPtr(%[[DECLB]]#1 : !fir.ref<i32>) -> !fir.ref<i32> {name = "b"}
+! CHECK: %[[DECLB:.*]]:2 = hlfir.declare %[[B]]
+! CHECK: %[[RED_B:.*]] = acc.reduction varPtr(%[[DECLB]]#1 : !fir.ref<i32>) -> !fir.ref<i32> {name = "b"}
! CHECK: acc.loop reduction(@reduction_min_ref_i32 -> %[[RED_B]] : !fir.ref<i32>)
subroutine acc_reduction_min_int_array_1d(a, b)
@@ -898,9 +886,8 @@ end subroutine
! CHECK-LABEL: func.func @_QPacc_reduction_min_int_array_1d(
! CHECK-SAME: %{{.*}}: !fir.ref<!fir.array<100xi32>> {fir.bindc_name = "a"}, %[[ARG1:.*]]: !fir.ref<!fir.array<100xi32>> {fir.bindc_name = "b"})
-! HLFIR: %[[DECLARG1:.*]]:2 = hlfir.declare %[[ARG1]]
-! FIR: %[[RED_ARG1:.*]] = acc.reduction varPtr(%[[ARG1]] : !fir.ref<!fir.array<100xi32>>) bounds(%2) -> !fir.ref<!fir.array<100xi32>> {name = "b"}
-! HLFIR: %[[RED_ARG1:.*]] = acc.reduction varPtr(%[[DECLARG1]]#1 : !fir.ref<!fir.array<100xi32>>) bounds(%{{.*}}) -> !fir.ref<!fir.array<100xi32>> {name = "b"}
+! CHECK: %[[DECLARG1:.*]]:2 = hlfir.declare %[[ARG1]]
+! CHECK: %[[RED_ARG1:.*]] = acc.reduction varPtr(%[[DECLARG1]]#1 : !fir.ref<!fir.array<100xi32>>) bounds(%{{.*}}) -> !fir.ref<!fir.array<100xi32>> {name = "b"}
! CHECK: acc.loop reduction(@reduction_min_section_ext100_ref_100xi32 -> %[[RED_ARG1]] : !fir.ref<!fir.array<100xi32>>)
subroutine acc_reduction_min_float(a, b)
@@ -915,9 +902,8 @@ end subroutine
! CHECK-LABEL: func.func @_QPacc_reduction_min_float(
! CHECK-SAME: %{{.*}}: !fir.ref<!fir.array<100xf32>> {fir.bindc_name = "a"}, %[[B:.*]]: !fir.ref<f32> {fir.bindc_name = "b"})
-! HLFIR: %[[DECLB:.*]]:2 = hlfir.declare %[[B]]
-! FIR: %[[RED_B:.*]] = acc.reduction varPtr(%[[B]] : !fir.ref<f32>) -> !fir.ref<f32> {name = "b"}
-! HLFIR: %[[RED_B:.*]] = acc.reduction varPtr(%[[DECLB]]#1 : !fir.ref<f32>) -> !fir.ref<f32> {name = "b"}
+! CHECK: %[[DECLB:.*]]:2 = hlfir.declare %[[B]]
+! CHECK: %[[RED_B:.*]] = acc.reduction varPtr(%[[DECLB]]#1 : !fir.ref<f32>) -> !fir.ref<f32> {name = "b"}
! CHECK: acc.loop reduction(@reduction_min_ref_f32 -> %[[RED_B]] : !fir.ref<f32>)
subroutine acc_reduction_min_float_array2d(a, b)
@@ -934,9 +920,8 @@ end subroutine
! CHECK-LABEL: func.func @_QPacc_reduction_min_float_array2d(
! CHECK-SAME: %{{.*}}: !fir.ref<!fir.array<100x10xf32>> {fir.bindc_name = "a"}, %[[ARG1:.*]]: !fir.ref<!fir.array<100x10xf32>> {fir.bindc_name = "b"})
-! HLFIR: %[[DECLARG1:.*]]:2 = hlfir.declare %[[ARG1]]
-! FIR: %[[RED_ARG1:.*]] = acc.reduction varPtr(%[[ARG1]] : !fir.ref<!fir.array<100x10xf32>>) bounds(%3, %5) -> !fir.ref<!fir.array<100x10xf32>> {name = "b"}
-! HLFIR: %[[RED_ARG1:.*]] = acc.reduction varPtr(%[[DECLARG1]]#1 : !fir.ref<!fir.array<100x10xf32>>) bounds(%{{.*}}, %{{.*}}) -> !fir.ref<!fir.array<100x10xf32>> {name = "b"}
+! CHECK: %[[DECLARG1:.*]]:2 = hlfir.declare %[[ARG1]]
+! CHECK: %[[RED_ARG1:.*]] = acc.reduction varPtr(%[[DECLARG1]]#1 : !fir.ref<!fir.array<100x10xf32>>) bounds(%{{.*}}, %{{.*}}) -> !fir.ref<!fir.array<100x10xf32>> {name = "b"}
! CHECK: acc.loop reduction(@reduction_min_section_ext100xext10_ref_100x10xf32 -> %[[RED_ARG1]] : !fir.ref<!fir.array<100x10xf32>>)
! CHECK: attributes {collapse = [2], collapseDeviceType = [#acc.device_type<none>]}
@@ -952,9 +937,8 @@ end subroutine
! CHECK-LABEL: func.func @_QPacc_reduction_max_int(
! CHECK-SAME: %{{.*}}: !fir.ref<!fir.array<100xi32>> {fir.bindc_name = "a"}, %[[B:.*]]: !fir.ref<i32> {fir.bindc_name = "b"})
-! HLFIR: %[[DECLB:.*]]:2 = hlfir.declare %[[B]]
-! FIR: %[[RED_B:.*]] = acc.reduction varPtr(%[[B]] : !fir.ref<i32>) -> !fir.ref<i32> {name = "b"}
-! HLFIR: %[[RED_B:.*]] = acc.reduction varPtr(%[[DECLB]]#1 : !fir.ref<i32>) -> !fir.ref<i32> {name = "b"}
+! CHECK: %[[DECLB:.*]]:2 = hlfir.declare %[[B]]
+! CHECK: %[[RED_B:.*]] = acc.reduction varPtr(%[[DECLB]]#1 : !fir.ref<i32>) -> !fir.ref<i32> {name = "b"}
! CHECK: acc.loop reduction(@reduction_max_ref_i32 -> %[[RED_B]] : !fir.ref<i32>)
subroutine acc_reduction_max_int_array2d(a, b)
@@ -971,9 +955,8 @@ end subroutine
! CHECK-LABEL: func.func @_QPacc_reduction_max_int_array2d(
! CHECK-SAME: %{{.*}}: !fir.ref<!fir.array<100x10xi32>> {fir.bindc_name = "a"}, %[[ARG1:.*]]: !fir.ref<!fir.array<100x10xi32>> {fir.bindc_name = "b"})
-! HLFIR: %[[DECLARG1:.*]]:2 = hlfir.declare %[[ARG1]]
-! FIR: %[[RED_ARG1:.*]] = acc.reduction varPtr(%[[ARG1]] : !fir.ref<!fir.array<100x10xi32>>) bounds(%{{.*}}, %{{.*}}) -> !fir.ref<!fir.array<100x10xi32>> {name = "b"}
-! HLFIR: %[[RED_ARG1:.*]] = acc.reduction varPtr(%[[DECLARG1]]#1 : !fir.ref<!fir.array<100x10xi32>>) bounds(%{{.*}}, %{{.*}}) -> !fir.ref<!fir.array<100x10xi32>> {name = "b"}
+! CHECK: %[[DECLARG1:.*]]:2 = hlfir.declare %[[ARG1]]
+! CHECK: %[[RED_ARG1:.*]] = acc.reduction varPtr(%[[DECLARG1]]#1 : !fir.ref<!fir.array<100x10xi32>>) bounds(%{{.*}}, %{{.*}}) -> !fir.ref<!fir.array<100x10xi32>> {name = "b"}
! CHECK: acc.loop reduction(@reduction_max_section_ext100xext10_ref_100x10xi32 -> %[[RED_ARG1]] : !fir.ref<!fir.array<100x10xi32>>)
subroutine acc_reduction_max_float(a, b)
@@ -988,9 +971,8 @@ end subroutine
! CHECK-LABEL: func.func @_QPacc_reduction_max_float(
! CHECK-SAME: %{{.*}}: !fir.ref<!fir.array<100xf32>> {fir.bindc_name = "a"}, %[[B:.*]]: !fir.ref<f32> {fir.bindc_name = "b"})
-! HLFIR: %[[DECLB:.*]]:2 = hlfir.declare %[[B]]
-! FIR: %[[RED_B:.*]] = acc.reduction varPtr(%[[B]] : !fir.ref<f32>) -> !fir.ref<f32> {name = "b"}
-! HLFIR: %[[RED_B:.*]] = acc.reduction varPtr(%[[DECLB]]#1 : !fir.ref<f32>) -> !fir.ref<f32> {name = "b"}
+! CHECK: %[[DECLB:.*]]:2 = hlfir.declare %[[B]]
+! CHECK: %[[RED_B:.*]] = acc.reduction varPtr(%[[DECLB]]#1 : !fir.ref<f32>) -> !fir.ref<f32> {name = "b"}
! CHECK: acc.loop reduction(@reduction_max_ref_f32 -> %[[RED_B]] : !fir.ref<f32>)
subroutine acc_reduction_max_float_array1d(a, b)
@@ -1005,9 +987,8 @@ end subroutine
! CHECK-LABEL: func.func @_QPacc_reduction_max_float_array1d(
! CHECK-SAME: %{{.*}}: !fir.ref<!fir.array<100xf32>> {fir.bindc_name = "a"}, %[[ARG1:.*]]: !fir.ref<!fir.array<100xf32>> {fir.bindc_name = "b"})
-! HLFIR: %[[DECLARG1:.*]]:2 = hlfir.declare %[[ARG1]]
-! FIR: %[[RED_ARG1:.*]] = acc.reduction varPtr(%[[ARG1]] : !fir.ref<!fir.array<100xf32>>) bounds(%{{.*}}) -> !fir.ref<!fir.array<100xf32>> {name = "b"}
-! HLFIR: %[[RED_ARG1:.*]] = acc.reduction varPtr(%[[DECLARG1]]#1 : !fir.ref<!fir.array<100xf32>>) bounds(%{{.*}}) -> !fir.ref<!fir.array<100xf32>> {name = "b"}
+! CHECK: %[[DECLARG1:.*]]:2 = hlfir.declare %[[ARG1]]
+! CHECK: %[[RED_ARG1:.*]] = acc.reduction varPtr(%[[DECLARG1]]#1 : !fir.ref<!fir.array<100xf32>>) bounds(%{{.*}}) -> !fir.ref<!fir.array<100xf32>> {name = "b"}
! CHECK: acc.loop reduction(@reduction_max_section_ext100_ref_100xf32 -> %[[RED_ARG1]] : !fir.ref<!fir.array<100xf32>>) {
subroutine acc_reduction_iand()
@@ -1048,9 +1029,8 @@ end subroutine
! CHECK-LABEL: func.func @_QPacc_reduction_and()
! CHECK: %[[L:.*]] = fir.alloca !fir.logical<4> {bindc_name = "l", uniq_name = "_QFacc_reduction_andEl"}
-! HLFIR: %[[DECLL:.*]]:2 = hlfir.declare %[[L]]
-! FIR: %[[RED:.*]] = acc.reduction varPtr(%[[L]] : !fir.ref<!fir.logical<4>>) -> !fir.ref<!fir.logical<4>> {name = "l"}
-! HLFIR: %[[RED:.*]] = acc.reduction varPtr(%[[DECLL]]#1 : !fir.ref<!fir.logical<4>>) -> !fir.ref<!fir.logical<4>> {name = "l"}
+! CHECK: %[[DECLL:.*]]:2 = hlfir.declare %[[L]]
+! CHECK: %[[RED:.*]] = acc.reduction varPtr(%[[DECLL]]#1 : !fir.ref<!fir.logical<4>>) -> !fir.ref<!fir.logical<4>> {name = "l"}
! CHECK: acc.parallel reduction(@reduction_land_ref_l32 -> %[[RED]] : !fir.ref<!fir.logical<4>>)
subroutine acc_reduction_or()
@@ -1112,9 +1092,8 @@ end subroutine
! CHECK-LABEL: func.func @_QPacc_reduction_add_alloc()
! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.box<!fir.heap<i32>> {bindc_name = "i", uniq_name = "_QFacc_reduction_add_allocEi"}
-! HLFIR: %[[DECL:.*]]:2 = hlfir.declare %[[ALLOCA]]
-! FIR: %[[LOAD:.*]] = fir.load %[[ALLOCA]] : !fir.ref<!fir.box<!fir.heap<i32>>>
-! HLFIR: %[[LOAD:.*]] = fir.load %[[DECL]]#1 : !fir.ref<!fir.box<!fir.heap<i32>>>
+! CHECK: %[[DECL:.*]]:2 = hlfir.declare %[[ALLOCA]]
+! CHECK: %[[LOAD:.*]] = fir.load %[[DECL]]#1 : !fir.ref<!fir.box<!fir.heap<i32>>>
! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[LOAD]] : (!fir.box<!fir.heap<i32>>) -> !fir.heap<i32>
! CHECK: %[[RED:.*]] = acc.reduction varPtr(%[[BOX_ADDR]] : !fir.heap<i32>) -> !fir.heap<i32> {name = "i"}
! CHECK: acc.parallel reduction(@reduction_add_heap_i32 -> %[[RED]] : !fir.heap<i32>)
@@ -1127,9 +1106,8 @@ end subroutine
! CHECK-LABEL: func.func @_QPacc_reduction_add_pointer(
! CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.box<!fir.ptr<i32>>> {fir.bindc_name = "i"})
-! HLFIR: %[[DECLARG0:.*]]:2 = hlfir.declare %[[ARG0]]
-! FIR: %[[LOAD:.*]] = fir.load %[[ARG0]] : !fir.ref<!fir.box<!fir.ptr<i32>>>
-! HLFIR: %[[LOAD:.*]] = fir.load %[[DECLARG0]]#1 : !fir.ref<!fir.box<!fir.ptr<i32>>>
+! CHECK: %[[DECLARG0:.*]]:2 = hlfir.declare %[[ARG0]]
+! CHECK: %[[LOAD:.*]] = fir.load %[[DECLARG0]]#1 : !fir.ref<!fir.box<!fir.ptr<i32>>>
! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[LOAD]] : (!fir.box<!fir.ptr<i32>>) -> !fir.ptr<i32>
! CHECK: %[[RED:.*]] = acc.reduction varPtr(%[[BOX_ADDR]] : !fir.ptr<i32>) -> !fir.ptr<i32> {name = "i"}
! CHECK: acc.parallel reduction(@reduction_add_ptr_i32 -> %[[RED]] : !fir.ptr<i32>)
@@ -1143,13 +1121,12 @@ end subroutine
! CHECK-LABEL: func.func @_QPacc_reduction_add_static_slice(
! CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.array<100xi32>> {fir.bindc_name = "a"})
! CHECK: %[[C100:.*]] = arith.constant 100 : index
-! HLFIR: %[[DECLARG0:.*]]:2 = hlfir.declare %[[ARG0]]
+! CHECK: %[[DECLARG0:.*]]:2 = hlfir.declare %[[ARG0]]
! CHECK: %[[C1:.*]] = arith.constant 1 : index
! CHECK: %[[LB:.*]] = arith.constant 10 : index
! CHECK: %[[UB:.*]] = arith.constant 19 : index
! CHECK: %[[BOUND:.*]] = acc.bounds lowerbound(%[[LB]] : index) upperbound(%[[UB]] : index) extent(%[[C100]] : index) stride(%[[C1]] : index) startIdx(%[[C1]] : index)
-! FIR: %[[RED:.*]] = acc.reduction varPtr(%[[ARG0]] : !fir.ref<!fir.array<100xi32>>) bounds(%[[BOUND]]) -> !fir.ref<!fir.array<100xi32>> {name = "a(11:20)"}
-! HLFIR: %[[RED:.*]] = acc.reduction varPtr(%[[DECLARG0]]#1 : !fir.ref<!fir.array<100xi32>>) bounds(%[[BOUND]]) -> !fir.ref<!fir.array<100xi32>> {name = "a(11:20)"}
+! CHECK: %[[RED:.*]] = acc.reduction varPtr(%[[DECLARG0]]#1 : !fir.ref<!fir.array<100xi32>>) bounds(%[[BOUND]]) -> !fir.ref<!fir.array<100xi32>> {name = "a(11:20)"}
! CHECK: acc.parallel reduction(@reduction_add_section_lb10.ub19_ref_100xi32 -> %[[RED]] : !fir.ref<!fir.array<100xi32>>)
subroutine acc_reduction_add_dynamic_extent_add(a)
@@ -1160,9 +1137,9 @@ end subroutine
! CHECK-LABEL: func.func @_QPacc_reduction_add_dynamic_extent_add(
! CHECK-SAME: %[[ARG0:.*]]: !fir.box<!fir.array<?xi32>> {fir.bindc_name = "a"})
-! HLFIR: %[[DECLARG0:.*]]:2 = hlfir.declare %[[ARG0]]
-! HLFIR: %[[RED:.*]] = acc.reduction varPtr(%{{.*}} : !fir.ref<!fir.array<?xi32>>) bounds(%{{.*}}) -> !fir.ref<!fir.array<?xi32>> {name = "a"}
-! HLFIR: acc.parallel reduction(@reduction_add_box_Uxi32 -> %[[RED:.*]] : !fir.ref<!fir.array<?xi32>>)
+! CHECK: %[[DECLARG0:.*]]:2 = hlfir.declare %[[ARG0]]
+! CHECK: %[[RED:.*]] = acc.reduction varPtr(%{{.*}} : !fir.ref<!fir.array<?xi32>>) bounds(%{{.*}}) -> !fir.ref<!fir.array<?xi32>> {name = "a"}
+! CHECK: acc.parallel reduction(@reduction_add_box_Uxi32 -> %[[RED:.*]] : !fir.ref<!fir.array<?xi32>>)
subroutine acc_reduction_add_assumed_shape_max(a)
real :: a(:)
@@ -1172,9 +1149,9 @@ end subroutine
! CHECK-LABEL: func.func @_QPacc_reduction_add_assumed_shape_max(
! CHECK-SAME: %[[ARG0:.*]]: !fir.box<!fir.array<?xf32>> {fir.bindc_name = "a"})
-! HLFIR: %[[DECLARG0:.*]]:2 = hlfir.declare %[[ARG0]]
-! HLFIR: %[[RED:.*]] = acc.reduction varPtr(%{{.*}} : !fir.ref<!fir.array<?xf32>>) bounds(%{{.*}}) -> !fir.ref<!fir.array<?xf32>> {name = "a"}
-! HLFIR: acc.parallel reduction(@reduction_max_box_Uxf32 -> %[[RED]] : !fir.ref<!fir.array<?xf32>>) {
+! CHECK: %[[DECLARG0:.*]]:2 = hlfir.declare %[[ARG0]]
+! CHECK: %[[RED:.*]] = acc.reduction varPtr(%{{.*}} : !fir.ref<!fir.array<?xf32>>) bounds(%{{.*}}) -> !fir.ref<!fir.array<?xf32>> {name = "a"}
+! CHECK: acc.parallel reduction(@reduction_max_box_Uxf32 -> %[[RED]] : !fir.ref<!fir.array<?xf32>>) {
subroutine acc_reduction_add_dynamic_extent_add_with_section(a)
integer :: a(:)
@@ -1184,11 +1161,11 @@ end subroutine
! CHECK-LABEL: func.func @_QPacc_reduction_add_dynamic_extent_add_with_section(
! CHECK-SAME: %[[ARG0:.*]]: !fir.box<!fir.array<?xi32>> {fir.bindc_name = "a"})
-! HLFIR: %[[DECL:.*]]:2 = hlfir.declare %[[ARG0]] {uniq_name = "_QFacc_reduction_add_dynamic_extent_add_with_sectionEa"} : (!fir.box<!fir.array<?xi32>>) -> (!fir.box<!fir.array<?xi32>>, !fir.box<!fir.array<?xi32>>)
-! HLFIR: %[[BOUND:.*]] = acc.bounds lowerbound(%c1{{.*}} : index) upperbound(%c3{{.*}} : index) extent(%{{.*}}#1 : index) stride(%{{.*}}#2 : index) startIdx(%{{.*}} : index) {strideInBytes = true}
-! HLFIR: %[[BOX_ADDR:.*]] = fir.box_addr %[[DECL]]#1 : (!fir.box<!fir.array<?xi32>>) -> !fir.ref<!fir.array<?xi32>>
-! HLFIR: %[[RED:.*]] = acc.reduction varPtr(%[[BOX_ADDR]] : !fir.ref<!fir.array<?xi32>>) bounds(%[[BOUND]]) -> !fir.ref<!fir.array<?xi32>> {name = "a(2:4)"}
-! HLFIR: acc.parallel reduction(@reduction_add_section_lb1.ub3_box_Uxi32 -> %[[RED]] : !fir.ref<!fir.array<?xi32>>)
+! CHECK: %[[DECL:.*]]:2 = hlfir.declare %[[ARG0]] {uniq_name = "_QFacc_reduction_add_dynamic_extent_add_with_sectionEa"} : (!fir.box<!fir.array<?xi32>>) -> (!fir.box<!fir.array<?xi32>>, !fir.box<!fir.array<?xi32>>)
+! CHECK: %[[BOUND:.*]] = acc.bounds lowerbound(%c1{{.*}} : index) upperbound(%c3{{.*}} : index) extent(%{{.*}}#1 : index) stride(%{{.*}}#2 : index) startIdx(%{{.*}} : index) {strideInBytes = true}
+! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[DECL]]#1 : (!fir.box<!fir.array<?xi32>>) -> !fir.ref<!fir.array<?xi32>>
+! CHECK: %[[RED:.*]] = acc.reduction varPtr(%[[BOX_ADDR]] : !fir.ref<!fir.array<?xi32>>) bounds(%[[BOUND]]) -> !fir.ref<!fir.array<?xi32>> {name = "a(2:4)"}
+! CHECK: acc.parallel reduction(@reduction_add_section_lb1.ub3_box_Uxi32 -> %[[RED]] : !fir.ref<!fir.array<?xi32>>)
subroutine acc_reduction_add_allocatable(a)
real, allocatable :: a(:)
@@ -1198,12 +1175,12 @@ end subroutine
! CHECK-LABEL: func.func @_QPacc_reduction_add_allocatable(
! CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>> {fir.bindc_name = "a"})
-! HLFIR: %[[DECL:.*]]:2 = hlfir.declare %[[ARG0]] {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFacc_reduction_add_allocatableEa"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>)
-! HLFIR: %[[BOX:.*]] = fir.load %[[DECL]]#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
-! HLFIR: %[[BOUND:.*]] = acc.bounds lowerbound(%c0{{.*}} : index) upperbound(%{{.*}} : index) extent(%{{.*}}#1 : index) stride(%{{.*}}#2 : index) startIdx(%{{.*}}#0 : index) {strideInBytes = true}
-! HLFIR: %[[BOX_ADDR:.*]] = fir.box_addr %[[BOX]] : (!fir.box<!fir.heap<!fir.array<?xf32>>>) -> !fir.heap<!fir.array<?xf32>>
-! HLFIR: %[[RED:.*]] = acc.reduction varPtr(%[[BOX_ADDR]] : !fir.heap<!fir.array<?xf32>>) bounds(%6) -> !fir.heap<!fir.array<?xf32>> {name = "a"}
-! HLFIR: acc.parallel reduction(@reduction_max_box_heap_Uxf32 -> %[[RED]] : !fir.heap<!fir.array<?xf32>>)
+! CHECK: %[[DECL:.*]]:2 = hlfir.declare %[[ARG0]] {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFacc_reduction_add_allocatableEa"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>)
+! CHECK: %[[BOX:.*]] = fir.load %[[DECL]]#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
+! CHECK: %[[BOUND:.*]] = acc.bounds lowerbound(%c0{{.*}} : index) upperbound(%{{.*}} : index) extent(%{{.*}}#1 : index) stride(%{{.*}}#2 : index) startIdx(%{{.*}}#0 : index) {strideInBytes = true}
+! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[BOX]] : (!fir.box<!fir.heap<!fir.array<?xf32>>>) -> !fir.heap<!fir.array<?xf32>>
+! CHECK: %[[RED:.*]] = acc.reduction varPtr(%[[BOX_ADDR]] : !fir.heap<!fir.array<?xf32>>) bounds(%6) -> !fir.heap<!fir.array<?xf32>> {name = "a"}
+! CHECK: acc.parallel reduction(@reduction_max_box_heap_Uxf32 -> %[[RED]] : !fir.heap<!fir.array<?xf32>>)
subroutine acc_reduction_add_pointer_array(a)
real, pointer :: a(:)
@@ -1213,12 +1190,12 @@ end subroutine
! CHECK-LABEL: func.func @_QPacc_reduction_add_pointer_array(
! CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>> {fir.bindc_name = "a"})
-! HLFIR: %[[DECL:.*]]:2 = hlfir.declare %[[ARG0]] {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFacc_reduction_add_pointer_arrayEa"} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>)
-! HLFIR: %[[BOX:.*]] = fir.load %[[DECL]]#1 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
-! HLFIR: %[[BOUND:.*]] = acc.bounds lowerbound(%c0{{.*}} : index) upperbound(%{{.*}} : index) extent(%{{.*}}#1 : index) stride(%{{.*}}#2 : index) startIdx(%{{.*}}#0 : index) {strideInBytes = true}
-! HLFIR: %[[BOX_ADDR:.*]] = fir.box_addr %[[BOX]] : (!fir.box<!fir.ptr<!fir.array<?xf32>>>) -> !fir.ptr<!fir.array<?xf32>>
-! HLFIR: %[[RED:.*]] = acc.reduction varPtr(%[[BOX_ADDR]] : !fir.ptr<!fir.array<?xf32>>) bounds(%[[BOUND]]) -> !fir.ptr<!fir.array<?xf32>> {name = "a"}
-! HLFIR: acc.parallel reduction(@reduction_max_box_ptr_Uxf32 -> %[[RED]] : !fir.ptr<!fir.array<?xf32>>)
+! CHECK: %[[DECL:.*]]:2 = hlfir.declare %[[ARG0]] {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFacc_reduction_add_pointer_arrayEa"} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>)
+! CHECK: %[[BOX:.*]] = fir.load %[[DECL]]#1 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
+! CHECK: %[[BOUND:.*]] = acc.bounds lowerbound(%c0{{.*}} : index) upperbound(%{{.*}} : index) extent(%{{.*}}#1 : index) stride(%{{.*}}#2 : index) startIdx(%{{.*}}#0 : index) {strideInBytes = true}
+! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[BOX]] : (!fir.box<!fir.ptr<!fir.array<?xf32>>>) -> !fir.ptr<!fir.array<?xf32>>
+! CHECK: %[[RED:.*]] = acc.reduction varPtr(%[[BOX_ADDR]] : !fir.ptr<!fir.array<?xf32>>) bounds(%[[BOUND]]) -> !fir.ptr<!fir.array<?xf32>> {name = "a"}
+! CHECK: acc.parallel reduction(@reduction_max_box_ptr_Uxf32 -> %[[RED]] : !fir.ptr<!fir.array<?xf32>>)
subroutine acc_reduction_max_dynamic_extent_max(a, n)
integer :: n
@@ -1229,6 +1206,6 @@ end subroutine
! CHECK-LABEL: func.func @_QPacc_reduction_max_dynamic_extent_max(
! CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.array<?x?xf32>> {fir.bindc_name = "a"}, %{{.*}}: !fir.ref<i32> {fir.bindc_name = "n"})
-! HLFIR: %[[DECL_A:.*]]:2 = hlfir.declare %[[ARG0]](%{{.*}}) {uniq_name = "_QFacc_reduction_max_dynamic_extent_maxEa"} : (!fir.ref<!fir.array<?x?xf32>>, !fir.shape<2>) -> (!fir.box<!fir.array<?x?xf32>>, !fir.ref<!fir.array<?x?xf32>>)
-! HLFIR: %[[RED:.*]] = acc.reduction varPtr(%[[DECL_A]]#1 : !fir.ref<!fir.array<?x?xf32>>) bounds(%{{.*}}, %{{.*}}) -> !fir.ref<!fir.array<?x?xf32>> {name = "a"}
-! HLFIR: acc.parallel reduction(@reduction_max_ref_UxUxf32 -> %[[RED]] : !fir.ref<!fir.array<?x?xf32>>)
+! CHECK: %[[DECL_A:.*]]:2 = hlfir.declare %[[ARG0]](%{{.*}}) {uniq_name = "_QFacc_reduction_max_dynamic_extent_maxEa"} : (!fir.ref<!fir.array<?x?xf32>>, !fir.shape<2>) -> (!fir.box<!fir.array<?x?xf32>>, !fir.ref<!fir.array<?x?xf32>>)
+! CHECK: %[[RED:.*]] = acc.reduction varPtr(%[[DECL_A]]#1 : !fir.ref<!fir.array<?x?xf32>>) bounds(%{{.*}}, %{{.*}}) -> !fir.ref<!fir.array<?x?xf32>> {name = "a"}
+! CHECK: acc.parallel reduction(@reduction_max_ref_UxUxf32 -> %[[RED]] : !fir.ref<!fir.array<?x?xf32>>)
diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst
index 893a3b13ca06..8ce5ec9f64ef 100644
--- a/libcxx/docs/FeatureTestMacroTable.rst
+++ b/libcxx/docs/FeatureTestMacroTable.rst
@@ -418,7 +418,7 @@ Status
--------------------------------------------------- -----------------
``__cpp_lib_freestanding_variant`` *unimplemented*
--------------------------------------------------- -----------------
- ``__cpp_lib_fstream_native_handle`` ``202306L``
+ ``__cpp_lib_fstream_native_handle`` *unimplemented*
--------------------------------------------------- -----------------
``__cpp_lib_function_ref`` *unimplemented*
--------------------------------------------------- -----------------
diff --git a/libcxx/docs/ReleaseNotes/18.rst b/libcxx/docs/ReleaseNotes/18.rst
index 882f53b8d9f8..cae2347be5fd 100644
--- a/libcxx/docs/ReleaseNotes/18.rst
+++ b/libcxx/docs/ReleaseNotes/18.rst
@@ -59,7 +59,6 @@ Implemented Papers
- P2909R4 - Fix formatting of code units as integers (Dude, where’s my ``char``?)
- P2821R5 - span.at()
- P0521R0 - Proposed Resolution for CA 14 (shared_ptr use_count/unique)
-- P1759R6 - Native handles and file streams
Improvements and New Features
diff --git a/libcxx/docs/Status/Cxx2cPapers.csv b/libcxx/docs/Status/Cxx2cPapers.csv
index 5701717f3976..fa4a112d1436 100644
--- a/libcxx/docs/Status/Cxx2cPapers.csv
+++ b/libcxx/docs/Status/Cxx2cPapers.csv
@@ -19,7 +19,7 @@
"`P2757R3 <https://wg21.link/P2757R3>`__","LWG","Type-checking format args","Varna June 2023","","","|format|"
"`P2637R3 <https://wg21.link/P2637R3>`__","LWG","Member ``visit``","Varna June 2023","","","|format|"
"`P2641R4 <https://wg21.link/P2641R4>`__","CWG, LWG","Checking if a ``union`` alternative is active","Varna June 2023","","",""
-"`P1759R6 <https://wg21.link/P1759R6>`__","LWG","Native handles and file streams","Varna June 2023","|Complete|","18.0",""
+"`P1759R6 <https://wg21.link/P1759R6>`__","LWG","Native handles and file streams","Varna June 2023","","",""
"`P2697R1 <https://wg21.link/P2697R1>`__","LWG","Interfacing ``bitset`` with ``string_view``","Varna June 2023","|Complete|","18.0",""
"`P1383R2 <https://wg21.link/P1383R2>`__","LWG","More ``constexpr`` for ``<cmath>`` and ``<complex>``","Varna June 2023","","",""
"`P2734R0 <https://wg21.link/P2734R0>`__","LWG","Adding the new SI prefixes","Varna June 2023","|Complete|","17.0",""
diff --git a/libcxx/include/fstream b/libcxx/include/fstream
index cd22b53efaad..7a4e15b55d56 100644
--- a/libcxx/include/fstream
+++ b/libcxx/include/fstream
@@ -73,7 +73,6 @@ public:
typedef typename traits_type::int_type int_type;
typedef typename traits_type::pos_type pos_type;
typedef typename traits_type::off_type off_type;
- using native_handle_type = typename basic_filebuf<charT, traits>::native_handle_type; // Since C++26
basic_ifstream();
explicit basic_ifstream(const char* s, ios_base::openmode mode = ios_base::in);
@@ -86,7 +85,6 @@ public:
void swap(basic_ifstream& rhs);
basic_filebuf<char_type, traits_type>* rdbuf() const;
- native_handle_type native_handle() const noexcept; // Since C++26
bool is_open() const;
void open(const char* s, ios_base::openmode mode = ios_base::in);
void open(const string& s, ios_base::openmode mode = ios_base::in);
@@ -112,7 +110,6 @@ public:
typedef typename traits_type::int_type int_type;
typedef typename traits_type::pos_type pos_type;
typedef typename traits_type::off_type off_type;
- using native_handle_type = typename basic_filebuf<charT, traits>::native_handle_type; // Since C++26
basic_ofstream();
explicit basic_ofstream(const char* s, ios_base::openmode mode = ios_base::out);
@@ -125,8 +122,6 @@ public:
void swap(basic_ofstream& rhs);
basic_filebuf<char_type, traits_type>* rdbuf() const;
- native_handle_type native_handle() const noexcept; // Since C++26
-
bool is_open() const;
void open(const char* s, ios_base::openmode mode = ios_base::out);
void open(const string& s, ios_base::openmode mode = ios_base::out);
@@ -153,7 +148,6 @@ public:
typedef typename traits_type::int_type int_type;
typedef typename traits_type::pos_type pos_type;
typedef typename traits_type::off_type off_type;
- using native_handle_type = typename basic_filebuf<charT, traits>::native_handle_type; // Since C++26
basic_fstream();
explicit basic_fstream(const char* s, ios_base::openmode mode = ios_base::in|ios_base::out);
@@ -166,7 +160,6 @@ public:
void swap(basic_fstream& rhs);
basic_filebuf<char_type, traits_type>* rdbuf() const;
- native_handle_type native_handle() const noexcept; // Since C++26
bool is_open() const;
void open(const char* s, ios_base::openmode mode = ios_base::in|ios_base::out);
void open(const string& s, ios_base::openmode mode = ios_base::in|ios_base::out);
@@ -217,10 +210,6 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD
-# if _LIBCPP_STD_VER >= 26 && defined(_LIBCPP_WIN32API)
-_LIBCPP_EXPORTED_FROM_ABI void* __filebuf_windows_native_handle(FILE* __file);
-# endif
-
template <class _CharT, class _Traits>
class _LIBCPP_TEMPLATE_VIS basic_filebuf : public basic_streambuf<_CharT, _Traits> {
public:
@@ -230,15 +219,6 @@ public:
typedef typename traits_type::pos_type pos_type;
typedef typename traits_type::off_type off_type;
typedef typename traits_type::state_type state_type;
-# if _LIBCPP_STD_VER >= 26
-# if defined(_LIBCPP_WIN32API)
- using native_handle_type = void*; // HANDLE
-# elif __has_include(<unistd.h>)
- using native_handle_type = int; // POSIX file descriptor
-# else
-# error "Provide a native file handle!"
-# endif
-# endif
// 27.9.1.2 Constructors/destructor:
basic_filebuf();
@@ -265,18 +245,6 @@ public:
# endif
_LIBCPP_HIDE_FROM_ABI basic_filebuf* __open(int __fd, ios_base::openmode __mode);
basic_filebuf* close();
-# if _LIBCPP_STD_VER >= 26
- _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() const noexcept {
- _LIBCPP_ASSERT_UNCATEGORIZED(this->is_open(), "File must be opened");
-# if defined(_LIBCPP_WIN32API)
- return std::__filebuf_windows_native_handle(__file_);
-# elif __has_include(<unistd.h>)
- return fileno(__file_);
-# else
-# error "Provide a way to determine the file native handle!"
-# endif
- }
-# endif // _LIBCPP_STD_VER >= 26
_LIBCPP_HIDE_FROM_ABI inline static const char* __make_mdstring(ios_base::openmode __mode) _NOEXCEPT;
@@ -1056,9 +1024,6 @@ public:
typedef typename traits_type::int_type int_type;
typedef typename traits_type::pos_type pos_type;
typedef typename traits_type::off_type off_type;
-# if _LIBCPP_STD_VER >= 26
- using native_handle_type = typename basic_filebuf<_CharT, _Traits>::native_handle_type;
-# endif
_LIBCPP_HIDE_FROM_ABI basic_ifstream();
_LIBCPP_HIDE_FROM_ABI explicit basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in);
@@ -1076,9 +1041,6 @@ public:
_LIBCPP_HIDE_FROM_ABI void swap(basic_ifstream& __rhs);
_LIBCPP_HIDE_FROM_ABI basic_filebuf<char_type, traits_type>* rdbuf() const;
-# if _LIBCPP_STD_VER >= 26
- _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() const noexcept { return rdbuf()->native_handle(); }
-# endif
_LIBCPP_HIDE_FROM_ABI bool is_open() const;
void open(const char* __s, ios_base::openmode __mode = ios_base::in);
# ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
@@ -1209,9 +1171,6 @@ public:
typedef typename traits_type::int_type int_type;
typedef typename traits_type::pos_type pos_type;
typedef typename traits_type::off_type off_type;
-# if _LIBCPP_STD_VER >= 26
- using native_handle_type = typename basic_filebuf<_CharT, _Traits>::native_handle_type;
-# endif
_LIBCPP_HIDE_FROM_ABI basic_ofstream();
_LIBCPP_HIDE_FROM_ABI explicit basic_ofstream(const char* __s, ios_base::openmode __mode = ios_base::out);
@@ -1231,9 +1190,6 @@ public:
_LIBCPP_HIDE_FROM_ABI void swap(basic_ofstream& __rhs);
_LIBCPP_HIDE_FROM_ABI basic_filebuf<char_type, traits_type>* rdbuf() const;
-# if _LIBCPP_STD_VER >= 26
- _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() const noexcept { return rdbuf()->native_handle(); }
-# endif
_LIBCPP_HIDE_FROM_ABI bool is_open() const;
void open(const char* __s, ios_base::openmode __mode = ios_base::out);
# ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
@@ -1365,9 +1321,6 @@ public:
typedef typename traits_type::int_type int_type;
typedef typename traits_type::pos_type pos_type;
typedef typename traits_type::off_type off_type;
-# if _LIBCPP_STD_VER >= 26
- using native_handle_type = typename basic_filebuf<_CharT, _Traits>::native_handle_type;
-# endif
_LIBCPP_HIDE_FROM_ABI basic_fstream();
_LIBCPP_HIDE_FROM_ABI explicit basic_fstream(const char* __s,
@@ -1392,9 +1345,6 @@ public:
_LIBCPP_HIDE_FROM_ABI void swap(basic_fstream& __rhs);
_LIBCPP_HIDE_FROM_ABI basic_filebuf<char_type, traits_type>* rdbuf() const;
-# if _LIBCPP_STD_VER >= 26
- _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() const noexcept { return rdbuf()->native_handle(); }
-# endif
_LIBCPP_HIDE_FROM_ABI bool is_open() const;
_LIBCPP_HIDE_FROM_ABI void open(const char* __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
# ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
diff --git a/libcxx/include/version b/libcxx/include/version
index c96647894dce..d3c2791a7d0b 100644
--- a/libcxx/include/version
+++ b/libcxx/include/version
@@ -496,7 +496,7 @@ __cpp_lib_within_lifetime 202306L <type_traits>
// # define __cpp_lib_freestanding_optional 202311L
// # define __cpp_lib_freestanding_string_view 202311L
// # define __cpp_lib_freestanding_variant 202311L
-# define __cpp_lib_fstream_native_handle 202306L
+// # define __cpp_lib_fstream_native_handle 202306L
// # define __cpp_lib_function_ref 202306L
// # define __cpp_lib_hazard_pointer 202306L
// # define __cpp_lib_linalg 202311L
diff --git a/libcxx/src/CMakeLists.txt b/libcxx/src/CMakeLists.txt
index 96e7c6362d8c..329964a00136 100644
--- a/libcxx/src/CMakeLists.txt
+++ b/libcxx/src/CMakeLists.txt
@@ -84,7 +84,6 @@ endif()
if (LIBCXX_ENABLE_LOCALIZATION)
list(APPEND LIBCXX_SOURCES
- fstream.cpp
include/sso_allocator.h
ios.cpp
ios.instantiations.cpp
diff --git a/libcxx/src/fstream.cpp b/libcxx/src/fstream.cpp
deleted file mode 100644
index 55a4442b9c78..000000000000
--- a/libcxx/src/fstream.cpp
+++ /dev/null
@@ -1,37 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#include <__config>
-#include <cstdio>
-#include <fstream>
-
-#if defined(_LIBCPP_WIN32API)
-# define WIN32_LEAN_AND_MEAN
-# define NOMINMAX
-# include <io.h>
-# include <windows.h>
-#endif
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-#if defined(_LIBCPP_WIN32API)
-
-// Confirm that `HANDLE` is `void*` as implemented in `basic_filebuf`
-static_assert(std::same_as<HANDLE, void*>);
-
-_LIBCPP_EXPORTED_FROM_ABI void* __filebuf_windows_native_handle(FILE* __file) noexcept {
- // https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/get-osfhandle?view=msvc-170
- intptr_t __handle = _get_osfhandle(fileno(__file));
- if (__handle == -1)
- return nullptr;
- return reinterpret_cast<void*>(__handle);
-}
-
-#endif
-
-_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/test/std/input.output/file.streams/fstreams/filebuf.members/native_handle.assert.pass.cpp b/libcxx/test/std/input.output/file.streams/fstreams/filebuf.members/native_handle.assert.pass.cpp
deleted file mode 100644
index 858f32e72165..000000000000
--- a/libcxx/test/std/input.output/file.streams/fstreams/filebuf.members/native_handle.assert.pass.cpp
+++ /dev/null
@@ -1,32 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23
-
-// REQUIRES: has-unix-headers
-// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
-// XFAIL: availability-verbose_abort-missing
-
-// <fstream>
-
-// class basic_filebuf;
-
-// native_handle_type native_handle() const noexcept;
-
-#include <fstream>
-
-#include "../native_handle_test_helpers.h"
-
-int main(int, char**) {
- test_native_handle_assertion<std::basic_filebuf<char>>();
-#ifndef TEST_HAS_NO_WIDE_CHARACTERS
- test_native_handle_assertion<std::basic_filebuf<wchar_t>>();
-#endif
-
- return 0;
-}
diff --git a/libcxx/test/std/input.output/file.streams/fstreams/filebuf.members/native_handle.pass.cpp b/libcxx/test/std/input.output/file.streams/fstreams/filebuf.members/native_handle.pass.cpp
deleted file mode 100644
index 22cc63e909c5..000000000000
--- a/libcxx/test/std/input.output/file.streams/fstreams/filebuf.members/native_handle.pass.cpp
+++ /dev/null
@@ -1,58 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23
-
-// <fstream>
-
-// class basic_filebuf;
-
-// native_handle_type native_handle() const noexcept;
-
-#include <cassert>
-#include <fstream>
-#include <filesystem>
-#include <utility>
-
-#include "platform_support.h"
-#include "test_macros.h"
-#include "../native_handle_test_helpers.h"
-
-template <typename CharT>
-void test() {
- std::basic_filebuf<CharT> f;
- std::filesystem::path p = get_temp_file_name();
-
- // non-const
- {
- assert(f.open(p, std::ios_base::in) != nullptr);
- std::same_as<NativeHandleT> decltype(auto) handle = f.native_handle();
- assert(is_handle_valid(handle));
- f.close();
- assert(!is_handle_valid(handle));
- static_assert(noexcept(f.native_handle()));
- }
- // const
- {
- assert(f.open(p, std::ios_base::in) != nullptr);
- std::same_as<NativeHandleT> decltype(auto) const_handle = std::as_const(f).native_handle();
- assert(is_handle_valid(const_handle));
- f.close();
- assert(!is_handle_valid(const_handle));
- static_assert(noexcept(std::as_const(f).native_handle()));
- }
-}
-
-int main(int, char**) {
- test<char>();
-#ifndef TEST_HAS_NO_WIDE_CHARACTERS
- test<wchar_t>();
-#endif
-
- return 0;
-}
diff --git a/libcxx/test/std/input.output/file.streams/fstreams/filebuf/types.pass.cpp b/libcxx/test/std/input.output/file.streams/fstreams/filebuf/types.pass.cpp
index 53a5f78d5eff..ad4249f4d809 100644
--- a/libcxx/test/std/input.output/file.streams/fstreams/filebuf/types.pass.cpp
+++ b/libcxx/test/std/input.output/file.streams/fstreams/filebuf/types.pass.cpp
@@ -23,7 +23,6 @@
#include <type_traits>
#include "test_macros.h"
-#include "../native_handle_test_helpers.h"
int main(int, char**)
{
@@ -33,12 +32,6 @@ int main(int, char**)
static_assert((std::is_same<std::basic_filebuf<char>::int_type, std::char_traits<char>::int_type>::value), "");
static_assert((std::is_same<std::basic_filebuf<char>::pos_type, std::char_traits<char>::pos_type>::value), "");
static_assert((std::is_same<std::basic_filebuf<char>::off_type, std::char_traits<char>::off_type>::value), "");
-#if TEST_STD_VER >= 26
- test_native_handle_type< std::basic_filebuf<char>>();
-# ifndef TEST_HAS_NO_WIDE_CHARACTERS
- test_native_handle_type< std::basic_filebuf<wchar_t>>();
-# endif
-#endif
- return 0;
+ return 0;
}
diff --git a/libcxx/test/std/input.output/file.streams/fstreams/fstream.members/native_handle.assert.pass.cpp b/libcxx/test/std/input.output/file.streams/fstreams/fstream.members/native_handle.assert.pass.cpp
deleted file mode 100644
index 2e6cadbc64e3..000000000000
--- a/libcxx/test/std/input.output/file.streams/fstreams/fstream.members/native_handle.assert.pass.cpp
+++ /dev/null
@@ -1,32 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23
-
-// REQUIRES: has-unix-headers
-// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
-// XFAIL: availability-verbose_abort-missing
-
-// <fstream>
-
-// class basic_fstream;
-
-// native_handle_type native_handle() const noexcept;
-
-#include <fstream>
-
-#include "../native_handle_test_helpers.h"
-
-int main(int, char**) {
- test_native_handle_assertion<std::basic_fstream<char>>();
-#ifndef TEST_HAS_NO_WIDE_CHARACTERS
- test_native_handle_assertion<std::basic_fstream<wchar_t>>();
-#endif
-
- return 0;
-}
diff --git a/libcxx/test/std/input.output/file.streams/fstreams/fstream.members/native_handle.pass.cpp b/libcxx/test/std/input.output/file.streams/fstreams/fstream.members/native_handle.pass.cpp
deleted file mode 100644
index a7229512385a..000000000000
--- a/libcxx/test/std/input.output/file.streams/fstreams/fstream.members/native_handle.pass.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23
-
-// <fstream>
-
-// class basic_fstream;
-
-// native_handle_type native_handle() const noexcept;
-
-#include "test_macros.h"
-#include "../native_handle_test_helpers.h"
-
-int main(int, char**) {
- test_native_handle<char, std::basic_fstream<char>>();
-#ifndef TEST_HAS_NO_WIDE_CHARACTERS
- test_native_handle<wchar_t, std::basic_fstream<wchar_t>>();
-#endif
-
- return 0;
-}
diff --git a/libcxx/test/std/input.output/file.streams/fstreams/fstream/types.pass.cpp b/libcxx/test/std/input.output/file.streams/fstreams/fstream/types.pass.cpp
index 0e275c53ed18..9274b1854bf8 100644
--- a/libcxx/test/std/input.output/file.streams/fstreams/fstream/types.pass.cpp
+++ b/libcxx/test/std/input.output/file.streams/fstreams/fstream/types.pass.cpp
@@ -23,7 +23,6 @@
#include <type_traits>
#include "test_macros.h"
-#include "../native_handle_test_helpers.h"
int main(int, char**)
{
@@ -33,12 +32,6 @@ int main(int, char**)
static_assert((std::is_same<std::basic_fstream<char>::int_type, std::char_traits<char>::int_type>::value), "");
static_assert((std::is_same<std::basic_fstream<char>::pos_type, std::char_traits<char>::pos_type>::value), "");
static_assert((std::is_same<std::basic_fstream<char>::off_type, std::char_traits<char>::off_type>::value), "");
-#if TEST_STD_VER >= 26
- test_native_handle_type< std::basic_fstream<char>>();
-# ifndef TEST_HAS_NO_WIDE_CHARACTERS
- test_native_handle_type< std::basic_fstream<wchar_t>>();
-# endif
-#endif
- return 0;
+ return 0;
}
diff --git a/libcxx/test/std/input.output/file.streams/fstreams/ifstream.members/native_handle.assert.pass.cpp b/libcxx/test/std/input.output/file.streams/fstreams/ifstream.members/native_handle.assert.pass.cpp
deleted file mode 100644
index 5e55b7303409..000000000000
--- a/libcxx/test/std/input.output/file.streams/fstreams/ifstream.members/native_handle.assert.pass.cpp
+++ /dev/null
@@ -1,32 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23
-
-// REQUIRES: has-unix-headers
-// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
-// XFAIL: availability-verbose_abort-missing
-
-// <fstream>
-
-// class basic_ifstream;
-
-// native_handle_type native_handle() const noexcept;
-
-#include <fstream>
-
-#include "../native_handle_test_helpers.h"
-
-int main(int, char**) {
- test_native_handle_assertion<std::basic_ifstream<char>>();
-#ifndef TEST_HAS_NO_WIDE_CHARACTERS
- test_native_handle_assertion<std::basic_ifstream<wchar_t>>();
-#endif
-
- return 0;
-}
diff --git a/libcxx/test/std/input.output/file.streams/fstreams/ifstream.members/native_handle.pass.cpp b/libcxx/test/std/input.output/file.streams/fstreams/ifstream.members/native_handle.pass.cpp
deleted file mode 100644
index c2aff949c8fa..000000000000
--- a/libcxx/test/std/input.output/file.streams/fstreams/ifstream.members/native_handle.pass.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23
-
-// <fstream>
-
-// class basic_ifstream;
-
-// native_handle_type native_handle() const noexcept;
-
-#include "test_macros.h"
-#include "../native_handle_test_helpers.h"
-
-int main(int, char**) {
- test_native_handle<char, std::basic_ifstream<char>>();
-#ifndef TEST_HAS_NO_WIDE_CHARACTERS
- test_native_handle<wchar_t, std::basic_ifstream<wchar_t>>();
-#endif
-
- return 0;
-}
diff --git a/libcxx/test/std/input.output/file.streams/fstreams/ifstream/types.pass.cpp b/libcxx/test/std/input.output/file.streams/fstreams/ifstream/types.pass.cpp
index 580e1ed22cba..15a044021f64 100644
--- a/libcxx/test/std/input.output/file.streams/fstreams/ifstream/types.pass.cpp
+++ b/libcxx/test/std/input.output/file.streams/fstreams/ifstream/types.pass.cpp
@@ -23,7 +23,6 @@
#include <type_traits>
#include "test_macros.h"
-#include "../native_handle_test_helpers.h"
int main(int, char**)
{
@@ -33,12 +32,6 @@ int main(int, char**)
static_assert((std::is_same<std::basic_ifstream<char>::int_type, std::char_traits<char>::int_type>::value), "");
static_assert((std::is_same<std::basic_ifstream<char>::pos_type, std::char_traits<char>::pos_type>::value), "");
static_assert((std::is_same<std::basic_ifstream<char>::off_type, std::char_traits<char>::off_type>::value), "");
-#if TEST_STD_VER >= 26
- test_native_handle_type< std::basic_ifstream<char>>();
-# ifndef TEST_HAS_NO_WIDE_CHARACTERS
- test_native_handle_type< std::basic_ifstream<wchar_t>>();
-# endif
-#endif
- return 0;
+ return 0;
}
diff --git a/libcxx/test/std/input.output/file.streams/fstreams/native_handle_test_helpers.h b/libcxx/test/std/input.output/file.streams/fstreams/native_handle_test_helpers.h
deleted file mode 100644
index 40bb2fe19487..000000000000
--- a/libcxx/test/std/input.output/file.streams/fstreams/native_handle_test_helpers.h
+++ /dev/null
@@ -1,97 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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 TEST_STD_INPUT_OUTPUT_FILE_STREAMS_FSTREAMS_TEST_HELPERS_H
-#define TEST_STD_INPUT_OUTPUT_FILE_STREAMS_FSTREAMS_TEST_HELPERS_H
-
-#include <cassert>
-#include <concepts>
-#include <cstdio>
-#include <fstream>
-#include <filesystem>
-#include <type_traits>
-#include <utility>
-
-#if defined(_WIN32)
-# include <io.h>
-# include <windows.h>
-#else
-# include <fcntl.h>
-#endif
-
-#include "platform_support.h"
-#include "test_macros.h"
-#include "types.h"
-
-#if TEST_STD_VER >= 26
-
-# include "check_assertion.h"
-
-inline bool is_handle_valid(NativeHandleT handle) {
-# if defined(_WIN32)
- BY_HANDLE_FILE_INFORMATION fileInformation;
- return GetFileInformationByHandle(handle, &fileInformation));
-# elif __has_include(<unistd.h>) // POSIX
- return fcntl(handle, F_GETFL) != -1 || errno != EBADF;
-# else
-# error "Provide a native file handle!"
-# endif
-}
-
-template <typename CharT, typename StreamT>
-inline void test_native_handle() {
- static_assert(
- std::is_same_v<typename std::basic_filebuf<CharT>::native_handle_type, typename StreamT::native_handle_type>);
-
- StreamT f;
- std::filesystem::path p = get_temp_file_name();
-
- // non-const
- {
- f.open(p);
- std::same_as<NativeHandleT> decltype(auto) handle = f.native_handle();
- assert(is_handle_valid(handle));
- assert(f.rdbuf()->native_handle() == handle);
- assert(std::as_const(f).rdbuf()->native_handle() == handle);
- f.close();
- assert(!is_handle_valid(handle));
- static_assert(noexcept(f.native_handle()));
- }
- // const
- {
- f.open(p);
- std::same_as<NativeHandleT> decltype(auto) const_handle = std::as_const(f).native_handle();
- assert(is_handle_valid(const_handle));
- assert(f.rdbuf()->native_handle() == const_handle);
- assert(std::as_const(f).rdbuf()->native_handle() == const_handle);
- f.close();
- assert(!is_handle_valid(const_handle));
- static_assert(noexcept(std::as_const(f).native_handle()));
- }
-}
-
-template <typename StreamT>
-inline void test_native_handle_assertion() {
- StreamT f;
-
- // non-const
- TEST_LIBCPP_ASSERT_FAILURE(f.native_handle(), "File must be opened");
- // const
- TEST_LIBCPP_ASSERT_FAILURE(std::as_const(f).native_handle(), "File must be opened");
-}
-
-template <typename StreamT>
-inline void test_native_handle_type() {
- static_assert(std::is_trivially_copyable_v<typename StreamT::native_handle_type>);
- static_assert(std::semiregular<typename StreamT::native_handle_type>);
- static_assert(std::is_same_v<typename StreamT::native_handle_type, NativeHandleT>);
-}
-
-#endif // #if TEST_STD_VER >= 26
-
-#endif // TEST_STD_INPUT_OUTPUT_FILE_STREAMS_FSTREAMS_TEST_HELPERS_H
diff --git a/libcxx/test/std/input.output/file.streams/fstreams/ofstream.members/native_handle.assert.pass.cpp b/libcxx/test/std/input.output/file.streams/fstreams/ofstream.members/native_handle.assert.pass.cpp
deleted file mode 100644
index d42aec1e99b9..000000000000
--- a/libcxx/test/std/input.output/file.streams/fstreams/ofstream.members/native_handle.assert.pass.cpp
+++ /dev/null
@@ -1,32 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23
-
-// REQUIRES: has-unix-headers
-// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
-// XFAIL: availability-verbose_abort-missing
-
-// <fstream>
-
-// class basic_ofstream;
-
-// native_handle_type native_handle() const noexcept;
-
-#include <fstream>
-
-#include "../native_handle_test_helpers.h"
-
-int main(int, char**) {
- test_native_handle_assertion<std::basic_ofstream<char>>();
-#ifndef TEST_HAS_NO_WIDE_CHARACTERS
- test_native_handle_assertion<std::basic_ofstream<wchar_t>>();
-#endif
-
- return 0;
-}
diff --git a/libcxx/test/std/input.output/file.streams/fstreams/ofstream.members/native_handle.pass.cpp b/libcxx/test/std/input.output/file.streams/fstreams/ofstream.members/native_handle.pass.cpp
deleted file mode 100644
index 88b3a00934cc..000000000000
--- a/libcxx/test/std/input.output/file.streams/fstreams/ofstream.members/native_handle.pass.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23
-
-// <fstream>
-
-// class basic_ofstream;
-
-// native_handle_type native_handle() const noexcept;
-
-#include "test_macros.h"
-#include "../native_handle_test_helpers.h"
-
-int main(int, char**) {
- test_native_handle<char, std::basic_ofstream<char>>();
-#ifndef TEST_HAS_NO_WIDE_CHARACTERS
- test_native_handle<wchar_t, std::basic_ofstream<wchar_t>>();
-#endif
-
- return 0;
-}
diff --git a/libcxx/test/std/input.output/file.streams/fstreams/ofstream/types.pass.cpp b/libcxx/test/std/input.output/file.streams/fstreams/ofstream/types.pass.cpp
index 242b4610af4a..0986d5907bac 100644
--- a/libcxx/test/std/input.output/file.streams/fstreams/ofstream/types.pass.cpp
+++ b/libcxx/test/std/input.output/file.streams/fstreams/ofstream/types.pass.cpp
@@ -23,7 +23,6 @@
#include <type_traits>
#include "test_macros.h"
-#include "../native_handle_test_helpers.h"
int main(int, char**)
{
@@ -33,12 +32,6 @@ int main(int, char**)
static_assert((std::is_same<std::basic_ofstream<char>::int_type, std::char_traits<char>::int_type>::value), "");
static_assert((std::is_same<std::basic_ofstream<char>::pos_type, std::char_traits<char>::pos_type>::value), "");
static_assert((std::is_same<std::basic_ofstream<char>::off_type, std::char_traits<char>::off_type>::value), "");
-#if TEST_STD_VER >= 26
- test_native_handle_type< std::basic_ofstream<char>>();
-# ifndef TEST_HAS_NO_WIDE_CHARACTERS
- test_native_handle_type< std::basic_ofstream<wchar_t>>();
-# endif
-#endif
- return 0;
+ return 0;
}
diff --git a/libcxx/test/std/input.output/file.streams/fstreams/types.h b/libcxx/test/std/input.output/file.streams/fstreams/types.h
index 29c8ad2d06c4..b919ba201853 100644
--- a/libcxx/test/std/input.output/file.streams/fstreams/types.h
+++ b/libcxx/test/std/input.output/file.streams/fstreams/types.h
@@ -80,14 +80,4 @@ struct LibraryDefaultBuffer {
void operator()(std::basic_ifstream<CharT>&) const {}
};
-#if TEST_STD_VER >= 26
-# if defined(_WIN32)
-using NativeHandleT = void*; // HANDLE
-# elif __has_include(<unistd.h>)
-using NativeHandleT = int; // POSIX file descriptor
-# else
-# error "Provide a native file handle!"
-# endif
-#endif
-
#endif // TEST_STD_INPUT_OUTPUT_FILE_STREAMS_FSTREAMS_TYPES_H
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/fstream.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/fstream.version.compile.pass.cpp
index eab0313b2c1e..981f5420ff7e 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/fstream.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/fstream.version.compile.pass.cpp
@@ -56,11 +56,17 @@
#elif TEST_STD_VER > 23
-# ifndef __cpp_lib_fstream_native_handle
-# error "__cpp_lib_fstream_native_handle should be defined in c++26"
-# endif
-# if __cpp_lib_fstream_native_handle != 202306L
-# error "__cpp_lib_fstream_native_handle should have the value 202306L in c++26"
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_fstream_native_handle
+# error "__cpp_lib_fstream_native_handle should be defined in c++26"
+# endif
+# if __cpp_lib_fstream_native_handle != 202306L
+# error "__cpp_lib_fstream_native_handle should have the value 202306L in c++26"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_fstream_native_handle
+# error "__cpp_lib_fstream_native_handle should not be defined because it is unimplemented in libc++!"
+# endif
# endif
#endif // TEST_STD_VER > 23
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
index d5a0839b30f8..3b7f2d26feeb 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
@@ -6511,11 +6511,17 @@
# endif
# endif
-# ifndef __cpp_lib_fstream_native_handle
-# error "__cpp_lib_fstream_native_handle should be defined in c++26"
-# endif
-# if __cpp_lib_fstream_native_handle != 202306L
-# error "__cpp_lib_fstream_native_handle should have the value 202306L in c++26"
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_fstream_native_handle
+# error "__cpp_lib_fstream_native_handle should be defined in c++26"
+# endif
+# if __cpp_lib_fstream_native_handle != 202306L
+# error "__cpp_lib_fstream_native_handle should have the value 202306L in c++26"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_fstream_native_handle
+# error "__cpp_lib_fstream_native_handle should not be defined because it is unimplemented in libc++!"
+# endif
# endif
# if !defined(_LIBCPP_VERSION)
diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py
index 8ee92909dfa5..3ad5170d73ff 100755
--- a/libcxx/utils/generate_feature_test_macro_components.py
+++ b/libcxx/utils/generate_feature_test_macro_components.py
@@ -570,6 +570,7 @@ feature_test_macros = [
"name": "__cpp_lib_fstream_native_handle",
"values": {"c++26": 202306}, # P1759R6 Native handles and file streams
"headers": ["fstream"],
+ "unimplemented": True,
},
{
"name": "__cpp_lib_function_ref",
diff --git a/llvm/include/llvm/Analysis/MemoryBuiltins.h b/llvm/include/llvm/Analysis/MemoryBuiltins.h
index 827b5081b2ce..d080a5956a4d 100644
--- a/llvm/include/llvm/Analysis/MemoryBuiltins.h
+++ b/llvm/include/llvm/Analysis/MemoryBuiltins.h
@@ -187,80 +187,125 @@ Value *lowerObjectSizeCall(
const TargetLibraryInfo *TLI, AAResults *AA, bool MustSucceed,
SmallVectorImpl<Instruction *> *InsertedInstructions = nullptr);
-using SizeOffsetType = std::pair<APInt, APInt>;
+/// SizeOffsetType - A base template class for the object size visitors. Used
+/// here as a self-documenting way to handle the values rather than using a
+/// \p std::pair.
+template <typename T, class C> class SizeOffsetType {
+public:
+ T Size;
+ T Offset;
+
+ SizeOffsetType() = default;
+ SizeOffsetType(T Size, T Offset) : Size(Size), Offset(Offset) {}
+
+ bool knownSize() const { return C::known(Size); }
+ bool knownOffset() const { return C::known(Offset); }
+ bool anyKnown() const { return knownSize() || knownOffset(); }
+ bool bothKnown() const { return knownSize() && knownOffset(); }
+
+ bool operator==(const SizeOffsetType<T, C> &RHS) const {
+ return Size == RHS.Size && Offset == RHS.Offset;
+ }
+ bool operator!=(const SizeOffsetType<T, C> &RHS) const {
+ return !(*this == RHS);
+ }
+};
+
+/// SizeOffsetAPInt - Used by \p ObjectSizeOffsetVisitor, which works with
+/// \p APInts.
+class SizeOffsetAPInt : public SizeOffsetType<APInt, SizeOffsetAPInt> {
+ friend class SizeOffsetType;
+ static bool known(APInt V) { return V.getBitWidth() > 1; }
+
+public:
+ SizeOffsetAPInt() = default;
+ SizeOffsetAPInt(APInt Size, APInt Offset) : SizeOffsetType(Size, Offset) {}
+};
/// Evaluate the size and offset of an object pointed to by a Value*
/// statically. Fails if size or offset are not known at compile time.
class ObjectSizeOffsetVisitor
- : public InstVisitor<ObjectSizeOffsetVisitor, SizeOffsetType> {
+ : public InstVisitor<ObjectSizeOffsetVisitor, SizeOffsetAPInt> {
const DataLayout &DL;
const TargetLibraryInfo *TLI;
ObjectSizeOpts Options;
unsigned IntTyBits;
APInt Zero;
- SmallDenseMap<Instruction *, SizeOffsetType, 8> SeenInsts;
+ SmallDenseMap<Instruction *, SizeOffsetAPInt, 8> SeenInsts;
unsigned InstructionsVisited;
APInt align(APInt Size, MaybeAlign Align);
- SizeOffsetType unknown() {
- return std::make_pair(APInt(), APInt());
- }
+ static SizeOffsetAPInt unknown() { return SizeOffsetAPInt(); }
public:
ObjectSizeOffsetVisitor(const DataLayout &DL, const TargetLibraryInfo *TLI,
LLVMContext &Context, ObjectSizeOpts Options = {});
- SizeOffsetType compute(Value *V);
-
- static bool knownSize(const SizeOffsetType &SizeOffset) {
- return SizeOffset.first.getBitWidth() > 1;
- }
-
- static bool knownOffset(const SizeOffsetType &SizeOffset) {
- return SizeOffset.second.getBitWidth() > 1;
- }
-
- static bool bothKnown(const SizeOffsetType &SizeOffset) {
- return knownSize(SizeOffset) && knownOffset(SizeOffset);
- }
+ SizeOffsetAPInt compute(Value *V);
// These are "private", except they can't actually be made private. Only
// compute() should be used by external users.
- SizeOffsetType visitAllocaInst(AllocaInst &I);
- SizeOffsetType visitArgument(Argument &A);
- SizeOffsetType visitCallBase(CallBase &CB);
- SizeOffsetType visitConstantPointerNull(ConstantPointerNull&);
- SizeOffsetType visitExtractElementInst(ExtractElementInst &I);
- SizeOffsetType visitExtractValueInst(ExtractValueInst &I);
- SizeOffsetType visitGlobalAlias(GlobalAlias &GA);
- SizeOffsetType visitGlobalVariable(GlobalVariable &GV);
- SizeOffsetType visitIntToPtrInst(IntToPtrInst&);
- SizeOffsetType visitLoadInst(LoadInst &I);
- SizeOffsetType visitPHINode(PHINode&);
- SizeOffsetType visitSelectInst(SelectInst &I);
- SizeOffsetType visitUndefValue(UndefValue&);
- SizeOffsetType visitInstruction(Instruction &I);
+ SizeOffsetAPInt visitAllocaInst(AllocaInst &I);
+ SizeOffsetAPInt visitArgument(Argument &A);
+ SizeOffsetAPInt visitCallBase(CallBase &CB);
+ SizeOffsetAPInt visitConstantPointerNull(ConstantPointerNull &);
+ SizeOffsetAPInt visitExtractElementInst(ExtractElementInst &I);
+ SizeOffsetAPInt visitExtractValueInst(ExtractValueInst &I);
+ SizeOffsetAPInt visitGlobalAlias(GlobalAlias &GA);
+ SizeOffsetAPInt visitGlobalVariable(GlobalVariable &GV);
+ SizeOffsetAPInt visitIntToPtrInst(IntToPtrInst &);
+ SizeOffsetAPInt visitLoadInst(LoadInst &I);
+ SizeOffsetAPInt visitPHINode(PHINode &);
+ SizeOffsetAPInt visitSelectInst(SelectInst &I);
+ SizeOffsetAPInt visitUndefValue(UndefValue &);
+ SizeOffsetAPInt visitInstruction(Instruction &I);
private:
- SizeOffsetType findLoadSizeOffset(
+ SizeOffsetAPInt findLoadSizeOffset(
LoadInst &LoadFrom, BasicBlock &BB, BasicBlock::iterator From,
- SmallDenseMap<BasicBlock *, SizeOffsetType, 8> &VisitedBlocks,
+ SmallDenseMap<BasicBlock *, SizeOffsetAPInt, 8> &VisitedBlocks,
unsigned &ScannedInstCount);
- SizeOffsetType combineSizeOffset(SizeOffsetType LHS, SizeOffsetType RHS);
- SizeOffsetType computeImpl(Value *V);
- SizeOffsetType computeValue(Value *V);
+ SizeOffsetAPInt combineSizeOffset(SizeOffsetAPInt LHS, SizeOffsetAPInt RHS);
+ SizeOffsetAPInt computeImpl(Value *V);
+ SizeOffsetAPInt computeValue(Value *V);
bool CheckedZextOrTrunc(APInt &I);
};
-using SizeOffsetEvalType = std::pair<Value *, Value *>;
+/// SizeOffsetValue - Used by \p ObjectSizeOffsetEvaluator, which works with
+/// \p Values.
+class SizeOffsetWeakTrackingVH;
+class SizeOffsetValue : public SizeOffsetType<Value *, SizeOffsetValue> {
+ friend class SizeOffsetType;
+ static bool known(Value *V) { return V != nullptr; }
+
+public:
+ SizeOffsetValue() : SizeOffsetType(nullptr, nullptr) {}
+ SizeOffsetValue(Value *Size, Value *Offset) : SizeOffsetType(Size, Offset) {}
+ SizeOffsetValue(const SizeOffsetWeakTrackingVH &SOT);
+};
+
+/// SizeOffsetWeakTrackingVH - Used by \p ObjectSizeOffsetEvaluator in a
+/// \p DenseMap.
+class SizeOffsetWeakTrackingVH
+ : public SizeOffsetType<WeakTrackingVH, SizeOffsetWeakTrackingVH> {
+ friend class SizeOffsetType;
+ static bool known(WeakTrackingVH V) { return V.pointsToAliveValue(); }
+
+public:
+ SizeOffsetWeakTrackingVH() : SizeOffsetType(nullptr, nullptr) {}
+ SizeOffsetWeakTrackingVH(Value *Size, Value *Offset)
+ : SizeOffsetType(Size, Offset) {}
+ SizeOffsetWeakTrackingVH(const SizeOffsetValue &SOV)
+ : SizeOffsetType(SOV.Size, SOV.Offset) {}
+};
/// Evaluate the size and offset of an object pointed to by a Value*.
/// May create code to compute the result at run-time.
class ObjectSizeOffsetEvaluator
- : public InstVisitor<ObjectSizeOffsetEvaluator, SizeOffsetEvalType> {
+ : public InstVisitor<ObjectSizeOffsetEvaluator, SizeOffsetValue> {
using BuilderTy = IRBuilder<TargetFolder, IRBuilderCallbackInserter>;
- using WeakEvalType = std::pair<WeakTrackingVH, WeakTrackingVH>;
+ using WeakEvalType = SizeOffsetWeakTrackingVH;
using CacheMapTy = DenseMap<const Value *, WeakEvalType>;
using PtrSetTy = SmallPtrSet<const Value *, 8>;
@@ -275,45 +320,27 @@ class ObjectSizeOffsetEvaluator
ObjectSizeOpts EvalOpts;
SmallPtrSet<Instruction *, 8> InsertedInstructions;
- SizeOffsetEvalType compute_(Value *V);
+ SizeOffsetValue compute_(Value *V);
public:
- static SizeOffsetEvalType unknown() {
- return std::make_pair(nullptr, nullptr);
- }
-
ObjectSizeOffsetEvaluator(const DataLayout &DL, const TargetLibraryInfo *TLI,
LLVMContext &Context, ObjectSizeOpts EvalOpts = {});
- SizeOffsetEvalType compute(Value *V);
-
- bool knownSize(SizeOffsetEvalType SizeOffset) {
- return SizeOffset.first;
- }
-
- bool knownOffset(SizeOffsetEvalType SizeOffset) {
- return SizeOffset.second;
- }
-
- bool anyKnown(SizeOffsetEvalType SizeOffset) {
- return knownSize(SizeOffset) || knownOffset(SizeOffset);
- }
+ static SizeOffsetValue unknown() { return SizeOffsetValue(); }
- bool bothKnown(SizeOffsetEvalType SizeOffset) {
- return knownSize(SizeOffset) && knownOffset(SizeOffset);
- }
+ SizeOffsetValue compute(Value *V);
// The individual instruction visitors should be treated as private.
- SizeOffsetEvalType visitAllocaInst(AllocaInst &I);
- SizeOffsetEvalType visitCallBase(CallBase &CB);
- SizeOffsetEvalType visitExtractElementInst(ExtractElementInst &I);
- SizeOffsetEvalType visitExtractValueInst(ExtractValueInst &I);
- SizeOffsetEvalType visitGEPOperator(GEPOperator &GEP);
- SizeOffsetEvalType visitIntToPtrInst(IntToPtrInst&);
- SizeOffsetEvalType visitLoadInst(LoadInst &I);
- SizeOffsetEvalType visitPHINode(PHINode &PHI);
- SizeOffsetEvalType visitSelectInst(SelectInst &I);
- SizeOffsetEvalType visitInstruction(Instruction &I);
+ SizeOffsetValue visitAllocaInst(AllocaInst &I);
+ SizeOffsetValue visitCallBase(CallBase &CB);
+ SizeOffsetValue visitExtractElementInst(ExtractElementInst &I);
+ SizeOffsetValue visitExtractValueInst(ExtractValueInst &I);
+ SizeOffsetValue visitGEPOperator(GEPOperator &GEP);
+ SizeOffsetValue visitIntToPtrInst(IntToPtrInst &);
+ SizeOffsetValue visitLoadInst(LoadInst &I);
+ SizeOffsetValue visitPHINode(PHINode &PHI);
+ SizeOffsetValue visitSelectInst(SelectInst &I);
+ SizeOffsetValue visitInstruction(Instruction &I);
};
} // end namespace llvm
diff --git a/llvm/include/llvm/CodeGen/CodeGenPassBuilder.h b/llvm/include/llvm/CodeGen/CodeGenPassBuilder.h
index a7cbb0910baa..2100c30aad11 100644
--- a/llvm/include/llvm/CodeGen/CodeGenPassBuilder.h
+++ b/llvm/include/llvm/CodeGen/CodeGenPassBuilder.h
@@ -38,6 +38,7 @@
#include "llvm/CodeGen/ReplaceWithVeclib.h"
#include "llvm/CodeGen/SafeStack.h"
#include "llvm/CodeGen/SelectOptimize.h"
+#include "llvm/CodeGen/ShadowStackGCLowering.h"
#include "llvm/CodeGen/SjLjEHPrepare.h"
#include "llvm/CodeGen/UnreachableBlockElim.h"
#include "llvm/CodeGen/WasmEHPrepare.h"
@@ -642,6 +643,9 @@ void CodeGenPassBuilder<Derived>::addIRPasses(AddIRPass &addPass) const {
// Run GC lowering passes for builtin collectors
// TODO: add a pass insertion point here
addPass(GCLoweringPass());
+ // FIXME: `ShadowStackGCLoweringPass` now is a
+ // module pass, so it will trigger assertion.
+ // See comment of `AddingFunctionPasses`
addPass(ShadowStackGCLoweringPass());
addPass(LowerConstantIntrinsicsPass());
diff --git a/llvm/include/llvm/CodeGen/MachinePassRegistry.def b/llvm/include/llvm/CodeGen/MachinePassRegistry.def
index f950dfae7e33..b1b8ee8df29d 100644
--- a/llvm/include/llvm/CodeGen/MachinePassRegistry.def
+++ b/llvm/include/llvm/CodeGen/MachinePassRegistry.def
@@ -26,6 +26,7 @@ MODULE_ANALYSIS("pass-instrumentation", PassInstrumentationAnalysis, (PIC))
MODULE_PASS("pre-isel-intrinsic-lowering", PreISelIntrinsicLoweringPass, ())
MODULE_PASS("jmc-instrumenter", JMCInstrumenterPass, ())
MODULE_PASS("lower-emutls", LowerEmuTLSPass, ())
+MODULE_PASS("shadow-stack-gc-lowering", ShadowStackGCLoweringPass, ())
#undef MODULE_PASS
#ifndef FUNCTION_ANALYSIS
@@ -133,7 +134,6 @@ MACHINE_FUNCTION_ANALYSIS("pass-instrumentation", PassInstrumentationAnalysis,
DUMMY_FUNCTION_PASS("atomic-expand", AtomicExpandPass, ())
DUMMY_FUNCTION_PASS("codegenprepare", CodeGenPreparePass, ())
DUMMY_FUNCTION_PASS("gc-lowering", GCLoweringPass, ())
-DUMMY_FUNCTION_PASS("shadow-stack-gc-lowering", ShadowStackGCLoweringPass, ())
DUMMY_FUNCTION_PASS("stack-protector", StackProtectorPass, ())
#undef DUMMY_FUNCTION_PASS
diff --git a/llvm/include/llvm/CodeGen/ShadowStackGCLowering.h b/llvm/include/llvm/CodeGen/ShadowStackGCLowering.h
new file mode 100644
index 000000000000..1586c6cf545b
--- /dev/null
+++ b/llvm/include/llvm/CodeGen/ShadowStackGCLowering.h
@@ -0,0 +1,24 @@
+//===- llvm/CodeGen/ShadowStackGCLowering.h ---------------------*- 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_CODEGEN_SHADOWSTACKGCLOWERING_H
+#define LLVM_CODEGEN_SHADOWSTACKGCLOWERING_H
+
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+class ShadowStackGCLoweringPass
+ : public PassInfoMixin<ShadowStackGCLoweringPass> {
+public:
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
+};
+
+} // namespace llvm
+
+#endif // LLVM_CODEGEN_SHADOWSTACKGCLOWERING_H
diff --git a/llvm/lib/Analysis/MemoryBuiltins.cpp b/llvm/lib/Analysis/MemoryBuiltins.cpp
index 9e6811f3bf88..46a7a921d86d 100644
--- a/llvm/lib/Analysis/MemoryBuiltins.cpp
+++ b/llvm/lib/Analysis/MemoryBuiltins.cpp
@@ -577,10 +577,12 @@ Value *llvm::getFreedOperand(const CallBase *CB, const TargetLibraryInfo *TLI) {
//===----------------------------------------------------------------------===//
// Utility functions to compute size of objects.
//
-static APInt getSizeWithOverflow(const SizeOffsetType &Data) {
- if (Data.second.isNegative() || Data.first.ult(Data.second))
- return APInt(Data.first.getBitWidth(), 0);
- return Data.first - Data.second;
+static APInt getSizeWithOverflow(const SizeOffsetAPInt &Data) {
+ APInt Size = Data.Size;
+ APInt Offset = Data.Offset;
+ if (Offset.isNegative() || Size.ult(Offset))
+ return APInt(Size.getBitWidth(), 0);
+ return Size - Offset;
}
/// Compute the size of the object pointed by Ptr. Returns true and the
@@ -590,8 +592,8 @@ static APInt getSizeWithOverflow(const SizeOffsetType &Data) {
bool llvm::getObjectSize(const Value *Ptr, uint64_t &Size, const DataLayout &DL,
const TargetLibraryInfo *TLI, ObjectSizeOpts Opts) {
ObjectSizeOffsetVisitor Visitor(DL, TLI, Ptr->getContext(), Opts);
- SizeOffsetType Data = Visitor.compute(const_cast<Value*>(Ptr));
- if (!Visitor.bothKnown(Data))
+ SizeOffsetAPInt Data = Visitor.compute(const_cast<Value *>(Ptr));
+ if (!Data.bothKnown())
return false;
Size = getSizeWithOverflow(Data).getZExtValue();
@@ -640,8 +642,7 @@ Value *llvm::lowerObjectSizeCall(
} else {
LLVMContext &Ctx = ObjectSize->getFunction()->getContext();
ObjectSizeOffsetEvaluator Eval(DL, TLI, Ctx, EvalOptions);
- SizeOffsetEvalType SizeOffsetPair =
- Eval.compute(ObjectSize->getArgOperand(0));
+ SizeOffsetValue SizeOffsetPair = Eval.compute(ObjectSize->getArgOperand(0));
if (SizeOffsetPair != ObjectSizeOffsetEvaluator::unknown()) {
IRBuilder<TargetFolder, IRBuilderCallbackInserter> Builder(
@@ -651,19 +652,19 @@ Value *llvm::lowerObjectSizeCall(
}));
Builder.SetInsertPoint(ObjectSize);
+ Value *Size = SizeOffsetPair.Size;
+ Value *Offset = SizeOffsetPair.Offset;
+
// If we've outside the end of the object, then we can always access
// exactly 0 bytes.
- Value *ResultSize =
- Builder.CreateSub(SizeOffsetPair.first, SizeOffsetPair.second);
- Value *UseZero =
- Builder.CreateICmpULT(SizeOffsetPair.first, SizeOffsetPair.second);
+ Value *ResultSize = Builder.CreateSub(Size, Offset);
+ Value *UseZero = Builder.CreateICmpULT(Size, Offset);
ResultSize = Builder.CreateZExtOrTrunc(ResultSize, ResultType);
Value *Ret = Builder.CreateSelect(
UseZero, ConstantInt::get(ResultType, 0), ResultSize);
// The non-constant size expression cannot evaluate to -1.
- if (!isa<Constant>(SizeOffsetPair.first) ||
- !isa<Constant>(SizeOffsetPair.second))
+ if (!isa<Constant>(Size) || !isa<Constant>(Offset))
Builder.CreateAssumption(
Builder.CreateICmpNE(Ret, ConstantInt::get(ResultType, -1)));
@@ -697,12 +698,12 @@ ObjectSizeOffsetVisitor::ObjectSizeOffsetVisitor(const DataLayout &DL,
// a different address space.
}
-SizeOffsetType ObjectSizeOffsetVisitor::compute(Value *V) {
+SizeOffsetAPInt ObjectSizeOffsetVisitor::compute(Value *V) {
InstructionsVisited = 0;
return computeImpl(V);
}
-SizeOffsetType ObjectSizeOffsetVisitor::computeImpl(Value *V) {
+SizeOffsetAPInt ObjectSizeOffsetVisitor::computeImpl(Value *V) {
unsigned InitialIntTyBits = DL.getIndexTypeSizeInBits(V->getType());
// Stripping pointer casts can strip address space casts which can change the
@@ -719,7 +720,7 @@ SizeOffsetType ObjectSizeOffsetVisitor::computeImpl(Value *V) {
IntTyBits = DL.getIndexTypeSizeInBits(V->getType());
Zero = APInt::getZero(IntTyBits);
- SizeOffsetType SOT = computeValue(V);
+ SizeOffsetAPInt SOT = computeValue(V);
bool IndexTypeSizeChanged = InitialIntTyBits != IntTyBits;
if (!IndexTypeSizeChanged && Offset.isZero())
@@ -729,27 +730,28 @@ SizeOffsetType ObjectSizeOffsetVisitor::computeImpl(Value *V) {
// accumulated some constant offset (or both). Readjust the bit width to match
// the argument index type size and apply the offset, as required.
if (IndexTypeSizeChanged) {
- if (knownSize(SOT) && !::CheckedZextOrTrunc(SOT.first, InitialIntTyBits))
- SOT.first = APInt();
- if (knownOffset(SOT) && !::CheckedZextOrTrunc(SOT.second, InitialIntTyBits))
- SOT.second = APInt();
+ if (SOT.knownSize() && !::CheckedZextOrTrunc(SOT.Size, InitialIntTyBits))
+ SOT.Size = APInt();
+ if (SOT.knownOffset() &&
+ !::CheckedZextOrTrunc(SOT.Offset, InitialIntTyBits))
+ SOT.Offset = APInt();
}
// If the computed offset is "unknown" we cannot add the stripped offset.
- return {SOT.first,
- SOT.second.getBitWidth() > 1 ? SOT.second + Offset : SOT.second};
+ return {SOT.Size,
+ SOT.Offset.getBitWidth() > 1 ? SOT.Offset + Offset : SOT.Offset};
}
-SizeOffsetType ObjectSizeOffsetVisitor::computeValue(Value *V) {
+SizeOffsetAPInt ObjectSizeOffsetVisitor::computeValue(Value *V) {
if (Instruction *I = dyn_cast<Instruction>(V)) {
// If we have already seen this instruction, bail out. Cycles can happen in
// unreachable code after constant propagation.
- auto P = SeenInsts.try_emplace(I, unknown());
+ auto P = SeenInsts.try_emplace(I, ObjectSizeOffsetVisitor::unknown());
if (!P.second)
return P.first->second;
++InstructionsVisited;
if (InstructionsVisited > ObjectSizeOffsetVisitorMaxVisitInstructions)
- return unknown();
- SizeOffsetType Res = visit(*I);
+ return ObjectSizeOffsetVisitor::unknown();
+ SizeOffsetAPInt Res = visit(*I);
// Cache the result for later visits. If we happened to visit this during
// the above recursion, we would consider it unknown until now.
SeenInsts[I] = Res;
@@ -768,55 +770,55 @@ SizeOffsetType ObjectSizeOffsetVisitor::computeValue(Value *V) {
LLVM_DEBUG(dbgs() << "ObjectSizeOffsetVisitor::compute() unhandled value: "
<< *V << '\n');
- return unknown();
+ return ObjectSizeOffsetVisitor::unknown();
}
bool ObjectSizeOffsetVisitor::CheckedZextOrTrunc(APInt &I) {
return ::CheckedZextOrTrunc(I, IntTyBits);
}
-SizeOffsetType ObjectSizeOffsetVisitor::visitAllocaInst(AllocaInst &I) {
+SizeOffsetAPInt ObjectSizeOffsetVisitor::visitAllocaInst(AllocaInst &I) {
TypeSize ElemSize = DL.getTypeAllocSize(I.getAllocatedType());
if (ElemSize.isScalable() && Options.EvalMode != ObjectSizeOpts::Mode::Min)
- return unknown();
+ return ObjectSizeOffsetVisitor::unknown();
APInt Size(IntTyBits, ElemSize.getKnownMinValue());
if (!I.isArrayAllocation())
- return std::make_pair(align(Size, I.getAlign()), Zero);
+ return SizeOffsetAPInt(align(Size, I.getAlign()), Zero);
Value *ArraySize = I.getArraySize();
if (const ConstantInt *C = dyn_cast<ConstantInt>(ArraySize)) {
APInt NumElems = C->getValue();
if (!CheckedZextOrTrunc(NumElems))
- return unknown();
+ return ObjectSizeOffsetVisitor::unknown();
bool Overflow;
Size = Size.umul_ov(NumElems, Overflow);
- return Overflow ? unknown()
- : std::make_pair(align(Size, I.getAlign()), Zero);
+ return Overflow ? ObjectSizeOffsetVisitor::unknown()
+ : SizeOffsetAPInt(align(Size, I.getAlign()), Zero);
}
- return unknown();
+ return ObjectSizeOffsetVisitor::unknown();
}
-SizeOffsetType ObjectSizeOffsetVisitor::visitArgument(Argument &A) {
+SizeOffsetAPInt ObjectSizeOffsetVisitor::visitArgument(Argument &A) {
Type *MemoryTy = A.getPointeeInMemoryValueType();
// No interprocedural analysis is done at the moment.
if (!MemoryTy|| !MemoryTy->isSized()) {
++ObjectVisitorArgument;
- return unknown();
+ return ObjectSizeOffsetVisitor::unknown();
}
APInt Size(IntTyBits, DL.getTypeAllocSize(MemoryTy));
- return std::make_pair(align(Size, A.getParamAlign()), Zero);
+ return SizeOffsetAPInt(align(Size, A.getParamAlign()), Zero);
}
-SizeOffsetType ObjectSizeOffsetVisitor::visitCallBase(CallBase &CB) {
+SizeOffsetAPInt ObjectSizeOffsetVisitor::visitCallBase(CallBase &CB) {
if (std::optional<APInt> Size = getAllocSize(&CB, TLI))
- return std::make_pair(*Size, Zero);
- return unknown();
+ return SizeOffsetAPInt(*Size, Zero);
+ return ObjectSizeOffsetVisitor::unknown();
}
-SizeOffsetType
-ObjectSizeOffsetVisitor::visitConstantPointerNull(ConstantPointerNull& CPN) {
+SizeOffsetAPInt
+ObjectSizeOffsetVisitor::visitConstantPointerNull(ConstantPointerNull &CPN) {
// If null is unknown, there's nothing we can do. Additionally, non-zero
// address spaces can make use of null, so we don't presume to know anything
// about that.
@@ -825,45 +827,46 @@ ObjectSizeOffsetVisitor::visitConstantPointerNull(ConstantPointerNull& CPN) {
// them on the floor, but it's unclear what we should do when a NULL from
// addrspace(1) gets casted to addrspace(0) (or vice-versa).
if (Options.NullIsUnknownSize || CPN.getType()->getAddressSpace())
- return unknown();
- return std::make_pair(Zero, Zero);
+ return ObjectSizeOffsetVisitor::unknown();
+ return SizeOffsetAPInt(Zero, Zero);
}
-SizeOffsetType
-ObjectSizeOffsetVisitor::visitExtractElementInst(ExtractElementInst&) {
- return unknown();
+SizeOffsetAPInt
+ObjectSizeOffsetVisitor::visitExtractElementInst(ExtractElementInst &) {
+ return ObjectSizeOffsetVisitor::unknown();
}
-SizeOffsetType
-ObjectSizeOffsetVisitor::visitExtractValueInst(ExtractValueInst&) {
+SizeOffsetAPInt
+ObjectSizeOffsetVisitor::visitExtractValueInst(ExtractValueInst &) {
// Easy cases were already folded by previous passes.
- return unknown();
+ return ObjectSizeOffsetVisitor::unknown();
}
-SizeOffsetType ObjectSizeOffsetVisitor::visitGlobalAlias(GlobalAlias &GA) {
+SizeOffsetAPInt ObjectSizeOffsetVisitor::visitGlobalAlias(GlobalAlias &GA) {
if (GA.isInterposable())
- return unknown();
+ return ObjectSizeOffsetVisitor::unknown();
return computeImpl(GA.getAliasee());
}
-SizeOffsetType ObjectSizeOffsetVisitor::visitGlobalVariable(GlobalVariable &GV){
+SizeOffsetAPInt
+ObjectSizeOffsetVisitor::visitGlobalVariable(GlobalVariable &GV) {
if (!GV.getValueType()->isSized() || GV.hasExternalWeakLinkage() ||
((!GV.hasInitializer() || GV.isInterposable()) &&
Options.EvalMode != ObjectSizeOpts::Mode::Min))
- return unknown();
+ return ObjectSizeOffsetVisitor::unknown();
APInt Size(IntTyBits, DL.getTypeAllocSize(GV.getValueType()));
- return std::make_pair(align(Size, GV.getAlign()), Zero);
+ return SizeOffsetAPInt(align(Size, GV.getAlign()), Zero);
}
-SizeOffsetType ObjectSizeOffsetVisitor::visitIntToPtrInst(IntToPtrInst&) {
+SizeOffsetAPInt ObjectSizeOffsetVisitor::visitIntToPtrInst(IntToPtrInst &) {
// clueless
- return unknown();
+ return ObjectSizeOffsetVisitor::unknown();
}
-SizeOffsetType ObjectSizeOffsetVisitor::findLoadSizeOffset(
+SizeOffsetAPInt ObjectSizeOffsetVisitor::findLoadSizeOffset(
LoadInst &Load, BasicBlock &BB, BasicBlock::iterator From,
- SmallDenseMap<BasicBlock *, SizeOffsetType, 8> &VisitedBlocks,
+ SmallDenseMap<BasicBlock *, SizeOffsetAPInt, 8> &VisitedBlocks,
unsigned &ScannedInstCount) {
constexpr unsigned MaxInstsToScan = 128;
@@ -871,10 +874,10 @@ SizeOffsetType ObjectSizeOffsetVisitor::findLoadSizeOffset(
if (Where != VisitedBlocks.end())
return Where->second;
- auto Unknown = [this, &BB, &VisitedBlocks]() {
- return VisitedBlocks[&BB] = unknown();
+ auto Unknown = [&BB, &VisitedBlocks]() {
+ return VisitedBlocks[&BB] = ObjectSizeOffsetVisitor::unknown();
};
- auto Known = [&BB, &VisitedBlocks](SizeOffsetType SO) {
+ auto Known = [&BB, &VisitedBlocks](SizeOffsetAPInt SO) {
return VisitedBlocks[&BB] = SO;
};
@@ -951,46 +954,47 @@ SizeOffsetType ObjectSizeOffsetVisitor::findLoadSizeOffset(
return Unknown();
} while (From-- != BB.begin());
- SmallVector<SizeOffsetType> PredecessorSizeOffsets;
+ SmallVector<SizeOffsetAPInt> PredecessorSizeOffsets;
for (auto *PredBB : predecessors(&BB)) {
PredecessorSizeOffsets.push_back(findLoadSizeOffset(
Load, *PredBB, BasicBlock::iterator(PredBB->getTerminator()),
VisitedBlocks, ScannedInstCount));
- if (!bothKnown(PredecessorSizeOffsets.back()))
+ if (!PredecessorSizeOffsets.back().bothKnown())
return Unknown();
}
if (PredecessorSizeOffsets.empty())
return Unknown();
- return Known(std::accumulate(PredecessorSizeOffsets.begin() + 1,
- PredecessorSizeOffsets.end(),
- PredecessorSizeOffsets.front(),
- [this](SizeOffsetType LHS, SizeOffsetType RHS) {
- return combineSizeOffset(LHS, RHS);
- }));
+ return Known(std::accumulate(
+ PredecessorSizeOffsets.begin() + 1, PredecessorSizeOffsets.end(),
+ PredecessorSizeOffsets.front(),
+ [this](SizeOffsetAPInt LHS, SizeOffsetAPInt RHS) {
+ return combineSizeOffset(LHS, RHS);
+ }));
}
-SizeOffsetType ObjectSizeOffsetVisitor::visitLoadInst(LoadInst &LI) {
+SizeOffsetAPInt ObjectSizeOffsetVisitor::visitLoadInst(LoadInst &LI) {
if (!Options.AA) {
++ObjectVisitorLoad;
- return unknown();
+ return ObjectSizeOffsetVisitor::unknown();
}
- SmallDenseMap<BasicBlock *, SizeOffsetType, 8> VisitedBlocks;
+ SmallDenseMap<BasicBlock *, SizeOffsetAPInt, 8> VisitedBlocks;
unsigned ScannedInstCount = 0;
- SizeOffsetType SO =
+ SizeOffsetAPInt SO =
findLoadSizeOffset(LI, *LI.getParent(), BasicBlock::iterator(LI),
VisitedBlocks, ScannedInstCount);
- if (!bothKnown(SO))
+ if (!SO.bothKnown())
++ObjectVisitorLoad;
return SO;
}
-SizeOffsetType ObjectSizeOffsetVisitor::combineSizeOffset(SizeOffsetType LHS,
- SizeOffsetType RHS) {
- if (!bothKnown(LHS) || !bothKnown(RHS))
- return unknown();
+SizeOffsetAPInt
+ObjectSizeOffsetVisitor::combineSizeOffset(SizeOffsetAPInt LHS,
+ SizeOffsetAPInt RHS) {
+ if (!LHS.bothKnown() || !RHS.bothKnown())
+ return ObjectSizeOffsetVisitor::unknown();
switch (Options.EvalMode) {
case ObjectSizeOpts::Mode::Min:
@@ -998,40 +1002,45 @@ SizeOffsetType ObjectSizeOffsetVisitor::combineSizeOffset(SizeOffsetType LHS,
case ObjectSizeOpts::Mode::Max:
return (getSizeWithOverflow(LHS).sgt(getSizeWithOverflow(RHS))) ? LHS : RHS;
case ObjectSizeOpts::Mode::ExactSizeFromOffset:
- return (getSizeWithOverflow(LHS).eq(getSizeWithOverflow(RHS))) ? LHS
- : unknown();
+ return (getSizeWithOverflow(LHS).eq(getSizeWithOverflow(RHS)))
+ ? LHS
+ : ObjectSizeOffsetVisitor::unknown();
case ObjectSizeOpts::Mode::ExactUnderlyingSizeAndOffset:
- return LHS == RHS ? LHS : unknown();
+ return LHS == RHS ? LHS : ObjectSizeOffsetVisitor::unknown();
}
llvm_unreachable("missing an eval mode");
}
-SizeOffsetType ObjectSizeOffsetVisitor::visitPHINode(PHINode &PN) {
+SizeOffsetAPInt ObjectSizeOffsetVisitor::visitPHINode(PHINode &PN) {
if (PN.getNumIncomingValues() == 0)
- return unknown();
+ return ObjectSizeOffsetVisitor::unknown();
auto IncomingValues = PN.incoming_values();
return std::accumulate(IncomingValues.begin() + 1, IncomingValues.end(),
computeImpl(*IncomingValues.begin()),
- [this](SizeOffsetType LHS, Value *VRHS) {
+ [this](SizeOffsetAPInt LHS, Value *VRHS) {
return combineSizeOffset(LHS, computeImpl(VRHS));
});
}
-SizeOffsetType ObjectSizeOffsetVisitor::visitSelectInst(SelectInst &I) {
+SizeOffsetAPInt ObjectSizeOffsetVisitor::visitSelectInst(SelectInst &I) {
return combineSizeOffset(computeImpl(I.getTrueValue()),
computeImpl(I.getFalseValue()));
}
-SizeOffsetType ObjectSizeOffsetVisitor::visitUndefValue(UndefValue&) {
- return std::make_pair(Zero, Zero);
+SizeOffsetAPInt ObjectSizeOffsetVisitor::visitUndefValue(UndefValue &) {
+ return SizeOffsetAPInt(Zero, Zero);
}
-SizeOffsetType ObjectSizeOffsetVisitor::visitInstruction(Instruction &I) {
+SizeOffsetAPInt ObjectSizeOffsetVisitor::visitInstruction(Instruction &I) {
LLVM_DEBUG(dbgs() << "ObjectSizeOffsetVisitor unknown instruction:" << I
<< '\n');
- return unknown();
+ return ObjectSizeOffsetVisitor::unknown();
}
+// Just set these right here...
+SizeOffsetValue::SizeOffsetValue(const SizeOffsetWeakTrackingVH &SOT)
+ : SizeOffsetType(SOT.Size, SOT.Offset) {}
+
ObjectSizeOffsetEvaluator::ObjectSizeOffsetEvaluator(
const DataLayout &DL, const TargetLibraryInfo *TLI, LLVMContext &Context,
ObjectSizeOpts EvalOpts)
@@ -1044,21 +1053,21 @@ ObjectSizeOffsetEvaluator::ObjectSizeOffsetEvaluator(
// be different for later objects.
}
-SizeOffsetEvalType ObjectSizeOffsetEvaluator::compute(Value *V) {
+SizeOffsetValue ObjectSizeOffsetEvaluator::compute(Value *V) {
// XXX - Are vectors of pointers possible here?
IntTy = cast<IntegerType>(DL.getIndexType(V->getType()));
Zero = ConstantInt::get(IntTy, 0);
- SizeOffsetEvalType Result = compute_(V);
+ SizeOffsetValue Result = compute_(V);
- if (!bothKnown(Result)) {
+ if (!Result.bothKnown()) {
// Erase everything that was computed in this iteration from the cache, so
// that no dangling references are left behind. We could be a bit smarter if
// we kept a dependency graph. It's probably not worth the complexity.
for (const Value *SeenVal : SeenVals) {
CacheMapTy::iterator CacheIt = CacheMap.find(SeenVal);
// non-computable results can be safely cached
- if (CacheIt != CacheMap.end() && anyKnown(CacheIt->second))
+ if (CacheIt != CacheMap.end() && CacheIt->second.anyKnown())
CacheMap.erase(CacheIt);
}
@@ -1074,12 +1083,12 @@ SizeOffsetEvalType ObjectSizeOffsetEvaluator::compute(Value *V) {
return Result;
}
-SizeOffsetEvalType ObjectSizeOffsetEvaluator::compute_(Value *V) {
+SizeOffsetValue ObjectSizeOffsetEvaluator::compute_(Value *V) {
ObjectSizeOffsetVisitor Visitor(DL, TLI, Context, EvalOpts);
- SizeOffsetType Const = Visitor.compute(V);
- if (Visitor.bothKnown(Const))
- return std::make_pair(ConstantInt::get(Context, Const.first),
- ConstantInt::get(Context, Const.second));
+ SizeOffsetAPInt Const = Visitor.compute(V);
+ if (Const.bothKnown())
+ return SizeOffsetValue(ConstantInt::get(Context, Const.Size),
+ ConstantInt::get(Context, Const.Offset));
V = V->stripPointerCasts();
@@ -1095,13 +1104,13 @@ SizeOffsetEvalType ObjectSizeOffsetEvaluator::compute_(Value *V) {
Builder.SetInsertPoint(I);
// Now compute the size and offset.
- SizeOffsetEvalType Result;
+ SizeOffsetValue Result;
// Record the pointers that were handled in this run, so that they can be
// cleaned later if something fails. We also use this set to break cycles that
// can occur in dead code.
if (!SeenVals.insert(V).second) {
- Result = unknown();
+ Result = ObjectSizeOffsetEvaluator::unknown();
} else if (GEPOperator *GEP = dyn_cast<GEPOperator>(V)) {
Result = visitGEPOperator(*GEP);
} else if (Instruction *I = dyn_cast<Instruction>(V)) {
@@ -1112,22 +1121,22 @@ SizeOffsetEvalType ObjectSizeOffsetEvaluator::compute_(Value *V) {
isa<GlobalAlias>(V) ||
isa<GlobalVariable>(V)) {
// Ignore values where we cannot do more than ObjectSizeVisitor.
- Result = unknown();
+ Result = ObjectSizeOffsetEvaluator::unknown();
} else {
LLVM_DEBUG(
dbgs() << "ObjectSizeOffsetEvaluator::compute() unhandled value: " << *V
<< '\n');
- Result = unknown();
+ Result = ObjectSizeOffsetEvaluator::unknown();
}
// Don't reuse CacheIt since it may be invalid at this point.
- CacheMap[V] = Result;
+ CacheMap[V] = SizeOffsetWeakTrackingVH(Result);
return Result;
}
-SizeOffsetEvalType ObjectSizeOffsetEvaluator::visitAllocaInst(AllocaInst &I) {
+SizeOffsetValue ObjectSizeOffsetEvaluator::visitAllocaInst(AllocaInst &I) {
if (!I.getAllocatedType()->isSized())
- return unknown();
+ return ObjectSizeOffsetEvaluator::unknown();
// must be a VLA
assert(I.isArrayAllocation());
@@ -1143,86 +1152,85 @@ SizeOffsetEvalType ObjectSizeOffsetEvaluator::visitAllocaInst(AllocaInst &I) {
Value *Size = ConstantInt::get(ArraySize->getType(),
DL.getTypeAllocSize(I.getAllocatedType()));
Size = Builder.CreateMul(Size, ArraySize);
- return std::make_pair(Size, Zero);
+ return SizeOffsetValue(Size, Zero);
}
-SizeOffsetEvalType ObjectSizeOffsetEvaluator::visitCallBase(CallBase &CB) {
+SizeOffsetValue ObjectSizeOffsetEvaluator::visitCallBase(CallBase &CB) {
std::optional<AllocFnsTy> FnData = getAllocationSize(&CB, TLI);
if (!FnData)
- return unknown();
+ return ObjectSizeOffsetEvaluator::unknown();
// Handle strdup-like functions separately.
if (FnData->AllocTy == StrDupLike) {
// TODO: implement evaluation of strdup/strndup
- return unknown();
+ return ObjectSizeOffsetEvaluator::unknown();
}
Value *FirstArg = CB.getArgOperand(FnData->FstParam);
FirstArg = Builder.CreateZExtOrTrunc(FirstArg, IntTy);
if (FnData->SndParam < 0)
- return std::make_pair(FirstArg, Zero);
+ return SizeOffsetValue(FirstArg, Zero);
Value *SecondArg = CB.getArgOperand(FnData->SndParam);
SecondArg = Builder.CreateZExtOrTrunc(SecondArg, IntTy);
Value *Size = Builder.CreateMul(FirstArg, SecondArg);
- return std::make_pair(Size, Zero);
+ return SizeOffsetValue(Size, Zero);
}
-SizeOffsetEvalType
-ObjectSizeOffsetEvaluator::visitExtractElementInst(ExtractElementInst&) {
- return unknown();
+SizeOffsetValue
+ObjectSizeOffsetEvaluator::visitExtractElementInst(ExtractElementInst &) {
+ return ObjectSizeOffsetEvaluator::unknown();
}
-SizeOffsetEvalType
-ObjectSizeOffsetEvaluator::visitExtractValueInst(ExtractValueInst&) {
- return unknown();
+SizeOffsetValue
+ObjectSizeOffsetEvaluator::visitExtractValueInst(ExtractValueInst &) {
+ return ObjectSizeOffsetEvaluator::unknown();
}
-SizeOffsetEvalType
-ObjectSizeOffsetEvaluator::visitGEPOperator(GEPOperator &GEP) {
- SizeOffsetEvalType PtrData = compute_(GEP.getPointerOperand());
- if (!bothKnown(PtrData))
- return unknown();
+SizeOffsetValue ObjectSizeOffsetEvaluator::visitGEPOperator(GEPOperator &GEP) {
+ SizeOffsetValue PtrData = compute_(GEP.getPointerOperand());
+ if (!PtrData.bothKnown())
+ return ObjectSizeOffsetEvaluator::unknown();
Value *Offset = emitGEPOffset(&Builder, DL, &GEP, /*NoAssumptions=*/true);
- Offset = Builder.CreateAdd(PtrData.second, Offset);
- return std::make_pair(PtrData.first, Offset);
+ Offset = Builder.CreateAdd(PtrData.Offset, Offset);
+ return SizeOffsetValue(PtrData.Size, Offset);
}
-SizeOffsetEvalType ObjectSizeOffsetEvaluator::visitIntToPtrInst(IntToPtrInst&) {
+SizeOffsetValue ObjectSizeOffsetEvaluator::visitIntToPtrInst(IntToPtrInst &) {
// clueless
- return unknown();
+ return ObjectSizeOffsetEvaluator::unknown();
}
-SizeOffsetEvalType ObjectSizeOffsetEvaluator::visitLoadInst(LoadInst &LI) {
- return unknown();
+SizeOffsetValue ObjectSizeOffsetEvaluator::visitLoadInst(LoadInst &LI) {
+ return ObjectSizeOffsetEvaluator::unknown();
}
-SizeOffsetEvalType ObjectSizeOffsetEvaluator::visitPHINode(PHINode &PHI) {
+SizeOffsetValue ObjectSizeOffsetEvaluator::visitPHINode(PHINode &PHI) {
// Create 2 PHIs: one for size and another for offset.
PHINode *SizePHI = Builder.CreatePHI(IntTy, PHI.getNumIncomingValues());
PHINode *OffsetPHI = Builder.CreatePHI(IntTy, PHI.getNumIncomingValues());
// Insert right away in the cache to handle recursive PHIs.
- CacheMap[&PHI] = std::make_pair(SizePHI, OffsetPHI);
+ CacheMap[&PHI] = SizeOffsetWeakTrackingVH(SizePHI, OffsetPHI);
// Compute offset/size for each PHI incoming pointer.
for (unsigned i = 0, e = PHI.getNumIncomingValues(); i != e; ++i) {
BasicBlock *IncomingBlock = PHI.getIncomingBlock(i);
Builder.SetInsertPoint(IncomingBlock, IncomingBlock->getFirstInsertionPt());
- SizeOffsetEvalType EdgeData = compute_(PHI.getIncomingValue(i));
+ SizeOffsetValue EdgeData = compute_(PHI.getIncomingValue(i));
- if (!bothKnown(EdgeData)) {
+ if (!EdgeData.bothKnown()) {
OffsetPHI->replaceAllUsesWith(PoisonValue::get(IntTy));
OffsetPHI->eraseFromParent();
InsertedInstructions.erase(OffsetPHI);
SizePHI->replaceAllUsesWith(PoisonValue::get(IntTy));
SizePHI->eraseFromParent();
InsertedInstructions.erase(SizePHI);
- return unknown();
+ return ObjectSizeOffsetEvaluator::unknown();
}
- SizePHI->addIncoming(EdgeData.first, IncomingBlock);
- OffsetPHI->addIncoming(EdgeData.second, IncomingBlock);
+ SizePHI->addIncoming(EdgeData.Size, IncomingBlock);
+ OffsetPHI->addIncoming(EdgeData.Offset, IncomingBlock);
}
Value *Size = SizePHI, *Offset = OffsetPHI;
@@ -1238,27 +1246,27 @@ SizeOffsetEvalType ObjectSizeOffsetEvaluator::visitPHINode(PHINode &PHI) {
OffsetPHI->eraseFromParent();
InsertedInstructions.erase(OffsetPHI);
}
- return std::make_pair(Size, Offset);
+ return SizeOffsetValue(Size, Offset);
}
-SizeOffsetEvalType ObjectSizeOffsetEvaluator::visitSelectInst(SelectInst &I) {
- SizeOffsetEvalType TrueSide = compute_(I.getTrueValue());
- SizeOffsetEvalType FalseSide = compute_(I.getFalseValue());
+SizeOffsetValue ObjectSizeOffsetEvaluator::visitSelectInst(SelectInst &I) {
+ SizeOffsetValue TrueSide = compute_(I.getTrueValue());
+ SizeOffsetValue FalseSide = compute_(I.getFalseValue());
- if (!bothKnown(TrueSide) || !bothKnown(FalseSide))
- return unknown();
+ if (!TrueSide.bothKnown() || !FalseSide.bothKnown())
+ return ObjectSizeOffsetEvaluator::unknown();
if (TrueSide == FalseSide)
return TrueSide;
- Value *Size = Builder.CreateSelect(I.getCondition(), TrueSide.first,
- FalseSide.first);
- Value *Offset = Builder.CreateSelect(I.getCondition(), TrueSide.second,
- FalseSide.second);
- return std::make_pair(Size, Offset);
+ Value *Size =
+ Builder.CreateSelect(I.getCondition(), TrueSide.Size, FalseSide.Size);
+ Value *Offset =
+ Builder.CreateSelect(I.getCondition(), TrueSide.Offset, FalseSide.Offset);
+ return SizeOffsetValue(Size, Offset);
}
-SizeOffsetEvalType ObjectSizeOffsetEvaluator::visitInstruction(Instruction &I) {
+SizeOffsetValue ObjectSizeOffsetEvaluator::visitInstruction(Instruction &I) {
LLVM_DEBUG(dbgs() << "ObjectSizeOffsetEvaluator unknown instruction:" << I
<< '\n');
- return unknown();
+ return ObjectSizeOffsetEvaluator::unknown();
}
diff --git a/llvm/lib/CodeGen/ShadowStackGCLowering.cpp b/llvm/lib/CodeGen/ShadowStackGCLowering.cpp
index d4840d117110..232e5e2bb886 100644
--- a/llvm/lib/CodeGen/ShadowStackGCLowering.cpp
+++ b/llvm/lib/CodeGen/ShadowStackGCLowering.cpp
@@ -15,9 +15,11 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/CodeGen/ShadowStackGCLowering.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Analysis/DomTreeUpdater.h"
+#include "llvm/CodeGen/GCMetadata.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Constant.h"
@@ -50,7 +52,7 @@ using namespace llvm;
namespace {
-class ShadowStackGCLowering : public FunctionPass {
+class ShadowStackGCLoweringImpl {
/// RootChain - This is the global linked-list that contains the chain of GC
/// roots.
GlobalVariable *Head = nullptr;
@@ -64,13 +66,10 @@ class ShadowStackGCLowering : public FunctionPass {
std::vector<std::pair<CallInst *, AllocaInst *>> Roots;
public:
- static char ID;
-
- ShadowStackGCLowering();
+ ShadowStackGCLoweringImpl() = default;
- bool doInitialization(Module &M) override;
- void getAnalysisUsage(AnalysisUsage &AU) const override;
- bool runOnFunction(Function &F) override;
+ bool doInitialization(Module &M);
+ bool runOnFunction(Function &F, DomTreeUpdater *DTU);
private:
bool IsNullValue(Value *V);
@@ -86,8 +85,51 @@ private:
const char *Name);
};
+class ShadowStackGCLowering : public FunctionPass {
+ ShadowStackGCLoweringImpl Impl;
+
+public:
+ static char ID;
+
+ ShadowStackGCLowering();
+
+ bool doInitialization(Module &M) override { return Impl.doInitialization(M); }
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.addPreserved<DominatorTreeWrapperPass>();
+ }
+ bool runOnFunction(Function &F) override {
+ std::optional<DomTreeUpdater> DTU;
+ if (auto *DTWP = getAnalysisIfAvailable<DominatorTreeWrapperPass>())
+ DTU.emplace(DTWP->getDomTree(), DomTreeUpdater::UpdateStrategy::Lazy);
+ return Impl.runOnFunction(F, DTU ? &*DTU : nullptr);
+ }
+};
+
} // end anonymous namespace
+PreservedAnalyses ShadowStackGCLoweringPass::run(Module &M,
+ ModuleAnalysisManager &MAM) {
+ auto &Map = MAM.getResult<CollectorMetadataAnalysis>(M);
+ if (Map.StrategyMap.contains("shadow-stack"))
+ return PreservedAnalyses::all();
+
+ ShadowStackGCLoweringImpl Impl;
+ bool Changed = Impl.doInitialization(M);
+ for (auto &F : M) {
+ auto &FAM =
+ MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
+ auto *DT = FAM.getCachedResult<DominatorTreeAnalysis>(F);
+ DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy);
+ Changed |= Impl.runOnFunction(F, DT ? &DTU : nullptr);
+ }
+
+ if (!Changed)
+ return PreservedAnalyses::all();
+ PreservedAnalyses PA;
+ PA.preserve<DominatorTreeAnalysis>();
+ return PA;
+}
+
char ShadowStackGCLowering::ID = 0;
char &llvm::ShadowStackGCLoweringID = ShadowStackGCLowering::ID;
@@ -104,7 +146,7 @@ ShadowStackGCLowering::ShadowStackGCLowering() : FunctionPass(ID) {
initializeShadowStackGCLoweringPass(*PassRegistry::getPassRegistry());
}
-Constant *ShadowStackGCLowering::GetFrameMap(Function &F) {
+Constant *ShadowStackGCLoweringImpl::GetFrameMap(Function &F) {
// doInitialization creates the abstract type of this value.
Type *VoidPtr = PointerType::getUnqual(F.getContext());
@@ -158,7 +200,7 @@ Constant *ShadowStackGCLowering::GetFrameMap(Function &F) {
return ConstantExpr::getGetElementPtr(FrameMap->getType(), GV, GEPIndices);
}
-Type *ShadowStackGCLowering::GetConcreteStackEntryType(Function &F) {
+Type *ShadowStackGCLoweringImpl::GetConcreteStackEntryType(Function &F) {
// doInitialization creates the generic version of this type.
std::vector<Type *> EltTys;
EltTys.push_back(StackEntryTy);
@@ -170,7 +212,7 @@ Type *ShadowStackGCLowering::GetConcreteStackEntryType(Function &F) {
/// doInitialization - If this module uses the GC intrinsics, find them now. If
/// not, exit fast.
-bool ShadowStackGCLowering::doInitialization(Module &M) {
+bool ShadowStackGCLoweringImpl::doInitialization(Module &M) {
bool Active = false;
for (Function &F : M) {
if (F.hasGC() && F.getGC() == "shadow-stack") {
@@ -224,13 +266,13 @@ bool ShadowStackGCLowering::doInitialization(Module &M) {
return true;
}
-bool ShadowStackGCLowering::IsNullValue(Value *V) {
+bool ShadowStackGCLoweringImpl::IsNullValue(Value *V) {
if (Constant *C = dyn_cast<Constant>(V))
return C->isNullValue();
return false;
}
-void ShadowStackGCLowering::CollectRoots(Function &F) {
+void ShadowStackGCLoweringImpl::CollectRoots(Function &F) {
// FIXME: Account for original alignment. Could fragment the root array.
// Approach 1: Null initialize empty slots at runtime. Yuck.
// Approach 2: Emit a map of the array instead of just a count.
@@ -258,11 +300,10 @@ void ShadowStackGCLowering::CollectRoots(Function &F) {
Roots.insert(Roots.begin(), MetaRoots.begin(), MetaRoots.end());
}
-GetElementPtrInst *ShadowStackGCLowering::CreateGEP(LLVMContext &Context,
- IRBuilder<> &B, Type *Ty,
- Value *BasePtr, int Idx,
- int Idx2,
- const char *Name) {
+GetElementPtrInst *
+ShadowStackGCLoweringImpl::CreateGEP(LLVMContext &Context, IRBuilder<> &B,
+ Type *Ty, Value *BasePtr, int Idx,
+ int Idx2, const char *Name) {
Value *Indices[] = {ConstantInt::get(Type::getInt32Ty(Context), 0),
ConstantInt::get(Type::getInt32Ty(Context), Idx),
ConstantInt::get(Type::getInt32Ty(Context), Idx2)};
@@ -273,9 +314,11 @@ GetElementPtrInst *ShadowStackGCLowering::CreateGEP(LLVMContext &Context,
return dyn_cast<GetElementPtrInst>(Val);
}
-GetElementPtrInst *ShadowStackGCLowering::CreateGEP(LLVMContext &Context,
- IRBuilder<> &B, Type *Ty, Value *BasePtr,
- int Idx, const char *Name) {
+GetElementPtrInst *ShadowStackGCLoweringImpl::CreateGEP(LLVMContext &Context,
+ IRBuilder<> &B,
+ Type *Ty,
+ Value *BasePtr, int Idx,
+ const char *Name) {
Value *Indices[] = {ConstantInt::get(Type::getInt32Ty(Context), 0),
ConstantInt::get(Type::getInt32Ty(Context), Idx)};
Value *Val = B.CreateGEP(Ty, BasePtr, Indices, Name);
@@ -285,12 +328,9 @@ GetElementPtrInst *ShadowStackGCLowering::CreateGEP(LLVMContext &Context,
return dyn_cast<GetElementPtrInst>(Val);
}
-void ShadowStackGCLowering::getAnalysisUsage(AnalysisUsage &AU) const {
- AU.addPreserved<DominatorTreeWrapperPass>();
-}
-
/// runOnFunction - Insert code to maintain the shadow stack.
-bool ShadowStackGCLowering::runOnFunction(Function &F) {
+bool ShadowStackGCLoweringImpl::runOnFunction(Function &F,
+ DomTreeUpdater *DTU) {
// Quick exit for functions that do not use the shadow stack GC.
if (!F.hasGC() || F.getGC() != "shadow-stack")
return false;
@@ -305,10 +345,6 @@ bool ShadowStackGCLowering::runOnFunction(Function &F) {
if (Roots.empty())
return false;
- std::optional<DomTreeUpdater> DTU;
- if (auto *DTWP = getAnalysisIfAvailable<DominatorTreeWrapperPass>())
- DTU.emplace(DTWP->getDomTree(), DomTreeUpdater::UpdateStrategy::Lazy);
-
// Build the constant map and figure the type of the shadow stack entry.
Value *FrameMap = GetFrameMap(F);
Type *ConcreteStackEntryTy = GetConcreteStackEntryType(F);
@@ -359,8 +395,7 @@ bool ShadowStackGCLowering::runOnFunction(Function &F) {
AtEntry.CreateStore(NewHeadVal, Head);
// For each instruction that escapes...
- EscapeEnumerator EE(F, "gc_cleanup", /*HandleExceptions=*/true,
- DTU ? &*DTU : nullptr);
+ EscapeEnumerator EE(F, "gc_cleanup", /*HandleExceptions=*/true, DTU);
while (IRBuilder<> *AtExit = EE.Next()) {
// Pop the entry from the shadow stack. Don't reuse CurrentHead from
// AtEntry, since that would make the value live for the entire function.
diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp
index 439f749bda8b..649451edc0e2 100644
--- a/llvm/lib/Passes/PassBuilder.cpp
+++ b/llvm/lib/Passes/PassBuilder.cpp
@@ -86,6 +86,7 @@
#include "llvm/CodeGen/LowerEmuTLS.h"
#include "llvm/CodeGen/SafeStack.h"
#include "llvm/CodeGen/SelectOptimize.h"
+#include "llvm/CodeGen/ShadowStackGCLowering.h"
#include "llvm/CodeGen/SjLjEHPrepare.h"
#include "llvm/CodeGen/TypePromotion.h"
#include "llvm/CodeGen/WasmEHPrepare.h"
diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def
index 82ce040c6496..eaa7c3fc8924 100644
--- a/llvm/lib/Passes/PassRegistry.def
+++ b/llvm/lib/Passes/PassRegistry.def
@@ -128,6 +128,7 @@ MODULE_PASS("sanmd-module", SanitizerBinaryMetadataPass())
MODULE_PASS("scc-oz-module-inliner",
buildInlinerPipeline(OptimizationLevel::Oz,
ThinOrFullLTOPhase::None))
+MODULE_PASS("shadow-stack-gc-lowering", ShadowStackGCLoweringPass())
MODULE_PASS("strip", StripSymbolsPass())
MODULE_PASS("strip-dead-debug-info", StripDeadDebugInfoPass())
MODULE_PASS("strip-dead-prototypes", StripDeadPrototypesPass())
diff --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
index b2618e35b085..cc5a4ee8c2bd 100644
--- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
+++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
@@ -6725,10 +6725,10 @@ struct AAHeapToStackFunction final : public AAHeapToStack {
LLVMContext &Ctx = AI.CB->getContext();
ObjectSizeOpts Opts;
ObjectSizeOffsetEvaluator Eval(DL, TLI, Ctx, Opts);
- SizeOffsetEvalType SizeOffsetPair = Eval.compute(AI.CB);
+ SizeOffsetValue SizeOffsetPair = Eval.compute(AI.CB);
assert(SizeOffsetPair != ObjectSizeOffsetEvaluator::unknown() &&
- cast<ConstantInt>(SizeOffsetPair.second)->isZero());
- Size = SizeOffsetPair.first;
+ cast<ConstantInt>(SizeOffsetPair.Offset)->isZero());
+ Size = SizeOffsetPair.Size;
}
Instruction *IP =
diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
index d4f5bf8c3935..e3deafa49bd9 100644
--- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
@@ -3665,10 +3665,14 @@ bool AddressSanitizer::isSafeAccess(ObjectSizeOffsetVisitor &ObjSizeVis,
// TODO: We can use vscale_range to convert a scalable value to an
// upper bound on the access size.
return false;
- SizeOffsetType SizeOffset = ObjSizeVis.compute(Addr);
- if (!ObjSizeVis.bothKnown(SizeOffset)) return false;
- uint64_t Size = SizeOffset.first.getZExtValue();
- int64_t Offset = SizeOffset.second.getSExtValue();
+
+ SizeOffsetAPInt SizeOffset = ObjSizeVis.compute(Addr);
+ if (!SizeOffset.bothKnown())
+ return false;
+
+ uint64_t Size = SizeOffset.Size.getZExtValue();
+ int64_t Offset = SizeOffset.Offset.getSExtValue();
+
// Three checks are required to ensure safety:
// . Offset >= 0 (since the offset is given from the base ptr)
// . Size >= Offset (unsigned)
diff --git a/llvm/lib/Transforms/Instrumentation/BoundsChecking.cpp b/llvm/lib/Transforms/Instrumentation/BoundsChecking.cpp
index ee5b81960417..cfa8ae26c625 100644
--- a/llvm/lib/Transforms/Instrumentation/BoundsChecking.cpp
+++ b/llvm/lib/Transforms/Instrumentation/BoundsChecking.cpp
@@ -61,15 +61,15 @@ static Value *getBoundsCheckCond(Value *Ptr, Value *InstVal,
LLVM_DEBUG(dbgs() << "Instrument " << *Ptr << " for " << Twine(NeededSize)
<< " bytes\n");
- SizeOffsetEvalType SizeOffset = ObjSizeEval.compute(Ptr);
+ SizeOffsetValue SizeOffset = ObjSizeEval.compute(Ptr);
- if (!ObjSizeEval.bothKnown(SizeOffset)) {
+ if (!SizeOffset.bothKnown()) {
++ChecksUnable;
return nullptr;
}
- Value *Size = SizeOffset.first;
- Value *Offset = SizeOffset.second;
+ Value *Size = SizeOffset.Size;
+ Value *Offset = SizeOffset.Offset;
ConstantInt *SizeCI = dyn_cast<ConstantInt>(Size);
Type *IndexTy = DL.getIndexType(Ptr->getType());
diff --git a/llvm/utils/gn/secondary/libcxx/src/BUILD.gn b/llvm/utils/gn/secondary/libcxx/src/BUILD.gn
index 5ba8a7cf4b91..c1211bb384d3 100644
--- a/llvm/utils/gn/secondary/libcxx/src/BUILD.gn
+++ b/llvm/utils/gn/secondary/libcxx/src/BUILD.gn
@@ -122,7 +122,6 @@ cxx_sources = [
"condition_variable_destructor.cpp",
"error_category.cpp",
"exception.cpp",
- "fstream.cpp",
"functional.cpp",
"future.cpp",
"hash.cpp",
@@ -146,7 +145,6 @@ cxx_sources = [
"iostream.cpp",
"legacy_pointer_safety.cpp",
"locale.cpp",
- "ostream.cpp",
"memory.cpp",
"memory_resource.cpp",
"mutex.cpp",
@@ -155,6 +153,7 @@ cxx_sources = [
"new_handler.cpp",
"new_helpers.cpp",
"optional.cpp",
+ "ostream.cpp",
"print.cpp",
"random.cpp",
"random_shuffle.cpp",