285 lines · plain
1// RUN: fir-opt %s --pass-pipeline="builtin.module(acc-initialize-fir-analyses,acc-implicit-data)" -split-input-file | FileCheck %s2 3// Test implicit firstprivate behavior for various scalar types in parallel and serial constructs.4// Scalars in parallel/serial constructs should be implicitly firstprivate according to OpenACC spec.5 6// -----7 8// CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_i32 : !fir.ref<i32> init {9// CHECK: ^bb0(%{{.*}}: !fir.ref<i32>):10// CHECK: %[[ALLOC:.*]] = fir.alloca i3211// CHECK: %[[DECL:.*]]:2 = hlfir.declare %[[ALLOC]]12// CHECK: acc.yield %[[DECL]]#0 : !fir.ref<i32>13// CHECK: } copy {14// CHECK: ^bb0(%[[SRC:.*]]: !fir.ref<i32>, %[[DST:.*]]: !fir.ref<i32>):15// CHECK: %[[LOADED:.*]] = fir.load %[[SRC]] : !fir.ref<i32>16// CHECK: fir.store %[[LOADED]] to %[[DST]] : !fir.ref<i32>17// CHECK: acc.terminator18// CHECK: }19 20// CHECK-LABEL: func.func @test_i32_scalar_in_parallel21func.func @test_i32_scalar_in_parallel() {22 %scalar = fir.alloca i32 {bindc_name = "i32_var"}23 acc.parallel {24 %load = fir.load %scalar : !fir.ref<i32>25 acc.yield26 }27 return28}29 30// CHECK: %[[FIRSTPRIV:.*]] = acc.firstprivate varPtr(%{{.*}} : !fir.ref<i32>) recipe(@firstprivatization_ref_i32) -> !fir.ref<i32> {implicit = true, name = "i32_var"}31// CHECK: acc.parallel firstprivate(%[[FIRSTPRIV]] : !fir.ref<i32>)32 33// -----34 35// CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_i64 : !fir.ref<i64> init {36// CHECK: ^bb0(%{{.*}}: !fir.ref<i64>):37// CHECK: %[[ALLOC:.*]] = fir.alloca i6438// CHECK: %[[DECL:.*]]:2 = hlfir.declare %[[ALLOC]]39// CHECK: acc.yield %[[DECL]]#0 : !fir.ref<i64>40// CHECK: } copy {41// CHECK: ^bb0(%[[SRC:.*]]: !fir.ref<i64>, %[[DST:.*]]: !fir.ref<i64>):42// CHECK: %[[LOADED:.*]] = fir.load %[[SRC]] : !fir.ref<i64>43// CHECK: fir.store %[[LOADED]] to %[[DST]] : !fir.ref<i64>44// CHECK: acc.terminator45// CHECK: }46 47// CHECK-LABEL: func.func @test_i64_scalar_in_parallel48func.func @test_i64_scalar_in_parallel() {49 %scalar = fir.alloca i64 {bindc_name = "i64_var"}50 acc.parallel {51 %load = fir.load %scalar : !fir.ref<i64>52 acc.yield53 }54 return55}56 57// CHECK: %[[FIRSTPRIV:.*]] = acc.firstprivate varPtr(%{{.*}} : !fir.ref<i64>) recipe(@firstprivatization_ref_i64) -> !fir.ref<i64> {implicit = true, name = "i64_var"}58// CHECK: acc.parallel firstprivate(%[[FIRSTPRIV]] : !fir.ref<i64>)59 60// -----61 62// CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_f32 : !fir.ref<f32> init {63// CHECK: ^bb0(%{{.*}}: !fir.ref<f32>):64// CHECK: %[[ALLOC:.*]] = fir.alloca f3265// CHECK: %[[DECL:.*]]:2 = hlfir.declare %[[ALLOC]]66// CHECK: acc.yield %[[DECL]]#0 : !fir.ref<f32>67// CHECK: } copy {68// CHECK: ^bb0(%[[SRC:.*]]: !fir.ref<f32>, %[[DST:.*]]: !fir.ref<f32>):69// CHECK: %[[LOADED:.*]] = fir.load %[[SRC]] : !fir.ref<f32>70// CHECK: fir.store %[[LOADED]] to %[[DST]] : !fir.ref<f32>71// CHECK: acc.terminator72// CHECK: }73 74// CHECK-LABEL: func.func @test_f32_scalar_in_parallel75func.func @test_f32_scalar_in_parallel() {76 %scalar = fir.alloca f32 {bindc_name = "f32_var"}77 acc.parallel {78 %load = fir.load %scalar : !fir.ref<f32>79 acc.yield80 }81 return82}83 84// CHECK: %[[FIRSTPRIV:.*]] = acc.firstprivate varPtr(%{{.*}} : !fir.ref<f32>) recipe(@firstprivatization_ref_f32) -> !fir.ref<f32> {implicit = true, name = "f32_var"}85// CHECK: acc.parallel firstprivate(%[[FIRSTPRIV]] : !fir.ref<f32>)86 87// -----88 89// CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_f64 : !fir.ref<f64> init {90// CHECK: ^bb0(%{{.*}}: !fir.ref<f64>):91// CHECK: %[[ALLOC:.*]] = fir.alloca f6492// CHECK: %[[DECL:.*]]:2 = hlfir.declare %[[ALLOC]]93// CHECK: acc.yield %[[DECL]]#0 : !fir.ref<f64>94// CHECK: } copy {95// CHECK: ^bb0(%[[SRC:.*]]: !fir.ref<f64>, %[[DST:.*]]: !fir.ref<f64>):96// CHECK: %[[LOADED:.*]] = fir.load %[[SRC]] : !fir.ref<f64>97// CHECK: fir.store %[[LOADED]] to %[[DST]] : !fir.ref<f64>98// CHECK: acc.terminator99// CHECK: }100 101// CHECK-LABEL: func.func @test_f64_scalar_in_parallel102func.func @test_f64_scalar_in_parallel() {103 %scalar = fir.alloca f64 {bindc_name = "f64_var"}104 acc.parallel {105 %load = fir.load %scalar : !fir.ref<f64>106 acc.yield107 }108 return109}110 111// CHECK: %[[FIRSTPRIV:.*]] = acc.firstprivate varPtr(%{{.*}} : !fir.ref<f64>) recipe(@firstprivatization_ref_f64) -> !fir.ref<f64> {implicit = true, name = "f64_var"}112// CHECK: acc.parallel firstprivate(%[[FIRSTPRIV]] : !fir.ref<f64>)113 114// -----115 116// CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_l32 : !fir.ref<!fir.logical<4>> init {117// CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.logical<4>>):118// CHECK: %[[ALLOC:.*]] = fir.alloca !fir.logical<4>119// CHECK: %[[DECL:.*]]:2 = hlfir.declare %[[ALLOC]]120// CHECK: acc.yield %[[DECL]]#0 : !fir.ref<!fir.logical<4>>121// CHECK: } copy {122// CHECK: ^bb0(%[[SRC:.*]]: !fir.ref<!fir.logical<4>>, %[[DST:.*]]: !fir.ref<!fir.logical<4>>):123// CHECK: %[[LOADED:.*]] = fir.load %[[SRC]] : !fir.ref<!fir.logical<4>>124// CHECK: fir.store %[[LOADED]] to %[[DST]] : !fir.ref<!fir.logical<4>>125// CHECK: acc.terminator126// CHECK: }127 128// CHECK-LABEL: func.func @test_logical_scalar_in_parallel129func.func @test_logical_scalar_in_parallel() {130 %scalar = fir.alloca !fir.logical<4> {bindc_name = "logical_var"}131 acc.parallel {132 %load = fir.load %scalar : !fir.ref<!fir.logical<4>>133 acc.yield134 }135 return136}137 138// CHECK: %[[FIRSTPRIV:.*]] = acc.firstprivate varPtr(%{{.*}} : !fir.ref<!fir.logical<4>>) recipe(@firstprivatization_ref_l32) -> !fir.ref<!fir.logical<4>> {implicit = true, name = "logical_var"}139// CHECK: acc.parallel firstprivate(%[[FIRSTPRIV]] : !fir.ref<!fir.logical<4>>)140 141// -----142 143// CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_z32 : !fir.ref<complex<f32>> init {144// CHECK: ^bb0(%{{.*}}: !fir.ref<complex<f32>>):145// CHECK: %[[ALLOC:.*]] = fir.alloca complex<f32>146// CHECK: %[[DECL:.*]]:2 = hlfir.declare %[[ALLOC]]147// CHECK: acc.yield %[[DECL]]#0 : !fir.ref<complex<f32>>148// CHECK: } copy {149// CHECK: ^bb0(%[[SRC:.*]]: !fir.ref<complex<f32>>, %[[DST:.*]]: !fir.ref<complex<f32>>):150// CHECK: %[[LOADED:.*]] = fir.load %[[SRC]] : !fir.ref<complex<f32>>151// CHECK: fir.store %[[LOADED]] to %[[DST]] : !fir.ref<complex<f32>>152// CHECK: acc.terminator153// CHECK: }154 155// CHECK-LABEL: func.func @test_complex_scalar_in_parallel156func.func @test_complex_scalar_in_parallel() {157 %scalar = fir.alloca complex<f32> {bindc_name = "complex_var"}158 acc.parallel {159 %load = fir.load %scalar : !fir.ref<complex<f32>>160 acc.yield161 }162 return163}164 165// CHECK: %[[FIRSTPRIV:.*]] = acc.firstprivate varPtr(%{{.*}} : !fir.ref<complex<f32>>) recipe(@firstprivatization_ref_z32) -> !fir.ref<complex<f32>> {implicit = true, name = "complex_var"}166// CHECK: acc.parallel firstprivate(%[[FIRSTPRIV]] : !fir.ref<complex<f32>>)167 168// -----169 170// CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_z64 : !fir.ref<complex<f64>> init {171// CHECK: ^bb0(%{{.*}}: !fir.ref<complex<f64>>):172// CHECK: %[[ALLOC:.*]] = fir.alloca complex<f64>173// CHECK: %[[DECL:.*]]:2 = hlfir.declare %[[ALLOC]]174// CHECK: acc.yield %[[DECL]]#0 : !fir.ref<complex<f64>>175// CHECK: } copy {176// CHECK: ^bb0(%[[SRC:.*]]: !fir.ref<complex<f64>>, %[[DST:.*]]: !fir.ref<complex<f64>>):177// CHECK: %[[LOADED:.*]] = fir.load %[[SRC]] : !fir.ref<complex<f64>>178// CHECK: fir.store %[[LOADED]] to %[[DST]] : !fir.ref<complex<f64>>179// CHECK: acc.terminator180// CHECK: }181 182// CHECK-LABEL: func.func @test_complex8_scalar_in_parallel183func.func @test_complex8_scalar_in_parallel() {184 %scalar = fir.alloca complex<f64> {bindc_name = "complex8_var"}185 acc.parallel {186 %load = fir.load %scalar : !fir.ref<complex<f64>>187 acc.yield188 }189 return190}191 192// CHECK: %[[FIRSTPRIV:.*]] = acc.firstprivate varPtr(%{{.*}} : !fir.ref<complex<f64>>) recipe(@firstprivatization_ref_z64) -> !fir.ref<complex<f64>> {implicit = true, name = "complex8_var"}193// CHECK: acc.parallel firstprivate(%[[FIRSTPRIV]] : !fir.ref<complex<f64>>)194 195// -----196 197// Test with serial construct198 199// CHECK-LABEL: func.func @test_i32_scalar_in_serial200func.func @test_i32_scalar_in_serial() {201 %scalar = fir.alloca i32 {bindc_name = "serial_i32_var"}202 acc.serial {203 %load = fir.load %scalar : !fir.ref<i32>204 acc.yield205 }206 return207}208 209// CHECK: %[[FIRSTPRIV:.*]] = acc.firstprivate varPtr(%{{.*}} : !fir.ref<i32>) recipe(@firstprivatization_ref_i32) -> !fir.ref<i32> {implicit = true, name = "serial_i32_var"}210// CHECK: acc.serial firstprivate(%[[FIRSTPRIV]] : !fir.ref<i32>)211 212// -----213 214// Test with serial construct and f64215 216// CHECK-LABEL: func.func @test_f64_scalar_in_serial217func.func @test_f64_scalar_in_serial() {218 %scalar = fir.alloca f64 {bindc_name = "serial_f64_var"}219 acc.serial {220 %load = fir.load %scalar : !fir.ref<f64>221 acc.yield222 }223 return224}225 226// CHECK: %[[FIRSTPRIV:.*]] = acc.firstprivate varPtr(%{{.*}} : !fir.ref<f64>) recipe(@firstprivatization_ref_f64) -> !fir.ref<f64> {implicit = true, name = "serial_f64_var"}227// CHECK: acc.serial firstprivate(%[[FIRSTPRIV]] : !fir.ref<f64>)228 229// -----230 231// Test i8 and i16 scalar types232 233// CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_i8 : !fir.ref<i8> init {234// CHECK: ^bb0(%{{.*}}: !fir.ref<i8>):235// CHECK: %[[ALLOC:.*]] = fir.alloca i8236// CHECK: %[[DECL:.*]]:2 = hlfir.declare %[[ALLOC]]237// CHECK: acc.yield %[[DECL]]#0 : !fir.ref<i8>238// CHECK: } copy {239// CHECK: ^bb0(%[[SRC:.*]]: !fir.ref<i8>, %[[DST:.*]]: !fir.ref<i8>):240// CHECK: %[[LOADED:.*]] = fir.load %[[SRC]] : !fir.ref<i8>241// CHECK: fir.store %[[LOADED]] to %[[DST]] : !fir.ref<i8>242// CHECK: acc.terminator243// CHECK: }244 245// CHECK-LABEL: func.func @test_i8_scalar_in_parallel246func.func @test_i8_scalar_in_parallel() {247 %scalar = fir.alloca i8 {bindc_name = "i8_var"}248 acc.parallel {249 %load = fir.load %scalar : !fir.ref<i8>250 acc.yield251 }252 return253}254 255// CHECK: %[[FIRSTPRIV:.*]] = acc.firstprivate varPtr(%{{.*}} : !fir.ref<i8>) recipe(@firstprivatization_ref_i8) -> !fir.ref<i8> {implicit = true, name = "i8_var"}256// CHECK: acc.parallel firstprivate(%[[FIRSTPRIV]] : !fir.ref<i8>)257 258// -----259 260// CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_i16 : !fir.ref<i16> init {261// CHECK: ^bb0(%{{.*}}: !fir.ref<i16>):262// CHECK: %[[ALLOC:.*]] = fir.alloca i16263// CHECK: %[[DECL:.*]]:2 = hlfir.declare %[[ALLOC]]264// CHECK: acc.yield %[[DECL]]#0 : !fir.ref<i16>265// CHECK: } copy {266// CHECK: ^bb0(%[[SRC:.*]]: !fir.ref<i16>, %[[DST:.*]]: !fir.ref<i16>):267// CHECK: %[[LOADED:.*]] = fir.load %[[SRC]] : !fir.ref<i16>268// CHECK: fir.store %[[LOADED]] to %[[DST]] : !fir.ref<i16>269// CHECK: acc.terminator270// CHECK: }271 272// CHECK-LABEL: func.func @test_i16_scalar_in_parallel273func.func @test_i16_scalar_in_parallel() {274 %scalar = fir.alloca i16 {bindc_name = "i16_var"}275 acc.parallel {276 %load = fir.load %scalar : !fir.ref<i16>277 acc.yield278 }279 return280}281 282// CHECK: %[[FIRSTPRIV:.*]] = acc.firstprivate varPtr(%{{.*}} : !fir.ref<i16>) recipe(@firstprivatization_ref_i16) -> !fir.ref<i16> {implicit = true, name = "i16_var"}283// CHECK: acc.parallel firstprivate(%[[FIRSTPRIV]] : !fir.ref<i16>)284 285