176 lines · plain
1// RUN: mlir-opt %s --pass-pipeline="builtin.module(acc-implicit-declare)" -split-input-file 2>&1 | FileCheck %s2 3// -----4 5// Test that non-constant scalar globals in compute regions are hoisted6// instead of being marked with acc declare7 8memref.global @gscalar : memref<f32> = dense<0.0>9 10func.func @test_scalar_in_serial() {11 acc.serial {12 %addr = memref.get_global @gscalar : memref<f32>13 %load = memref.load %addr[] : memref<f32>14 acc.yield15 }16 return17}18 19// Expected to hoist this global access out of acc region instead of marking20// with `acc declare`.21// CHECK-LABEL: func.func @test_scalar_in_serial22// CHECK: memref.get_global @gscalar23// CHECK: acc.serial24// CHECK-NOT: acc.declare25 26// -----27 28// Test that constant globals are marked with acc declare29 30memref.global constant @gscalarconst : memref<f32> = dense<1.0>31 32func.func @test_constant_in_serial() {33 acc.serial {34 %addr = memref.get_global @gscalarconst : memref<f32>35 %load = memref.load %addr[] : memref<f32>36 acc.yield37 }38 return39}40 41// This is expected to be `acc declare`'d since it is a constant.42// CHECK: memref.global constant @gscalarconst {{.*}} {acc.declare = #acc.declare<dataClause = acc_copyin>}43 44// -----45 46// Test globals referenced in acc routine functions47 48memref.global @gscalar_routine : memref<f32> = dense<0.0>49 50acc.routine @acc_routine_0 func(@test_scalar_in_accroutine)51func.func @test_scalar_in_accroutine() attributes {acc.routine_info = #acc.routine_info<[@acc_routine_0]>} {52 %addr = memref.get_global @gscalar_routine : memref<f32>53 %load = memref.load %addr[] : memref<f32>54 return55}56 57// Global should be acc declare'd because it's in an acc routine58// CHECK: memref.global @gscalar_routine {{.*}} {acc.declare = #acc.declare<dataClause = acc_copyin>}59 60// -----61 62// Test constant globals in acc routine63 64memref.global constant @gscalarconst_routine : memref<f32> = dense<1.0>65 66acc.routine @acc_routine_0 func(@test_constant_in_accroutine)67func.func @test_constant_in_accroutine() attributes {acc.routine_info = #acc.routine_info<[@acc_routine_0]>} {68 %addr = memref.get_global @gscalarconst_routine : memref<f32>69 %load = memref.load %addr[] : memref<f32>70 return71}72 73// CHECK: memref.global constant @gscalarconst_routine {{.*}} {acc.declare = #acc.declare<dataClause = acc_copyin>}74 75// -----76 77// Test acc.private.recipe with global reference - referenced variant78 79memref.global @global_for_private : memref<f32> = dense<0.0>80 81acc.private.recipe @private_recipe_with_global : memref<f32> init {82^bb0(%arg0: memref<f32>):83 %0 = memref.alloc() : memref<f32>84 %global_addr = memref.get_global @global_for_private : memref<f32>85 %global_val = memref.load %global_addr[] : memref<f32>86 memref.store %global_val, %0[] : memref<f32>87 acc.yield %0 : memref<f32>88} destroy {89^bb0(%arg0: memref<f32>):90 memref.dealloc %arg0 : memref<f32>91 acc.terminator92}93 94func.func @test_private_recipe_referenced() {95 %var = memref.alloc() : memref<f32>96 %priv = acc.private varPtr(%var : memref<f32>) recipe(@private_recipe_with_global) -> memref<f32>97 acc.parallel private(%priv : memref<f32>) {98 %load = memref.load %var[] : memref<f32>99 acc.yield100 }101 memref.dealloc %var : memref<f32>102 return103}104 105// Global should be acc declare'd because the recipe is referenced106// CHECK: memref.global @global_for_private {{.*}} {acc.declare = #acc.declare<dataClause = acc_copyin>}107 108// -----109 110// Test acc.private.recipe with global reference - unreferenced variant111 112memref.global @global_for_private_unused : memref<f32> = dense<0.0>113 114acc.private.recipe @private_recipe_unused : memref<f32> init {115^bb0(%arg0: memref<f32>):116 %0 = memref.alloc() : memref<f32>117 %global_addr = memref.get_global @global_for_private_unused : memref<f32>118 %global_val = memref.load %global_addr[] : memref<f32>119 memref.store %global_val, %0[] : memref<f32>120 acc.yield %0 : memref<f32>121} destroy {122^bb0(%arg0: memref<f32>):123 memref.dealloc %arg0 : memref<f32>124 acc.terminator125}126 127func.func @test_private_recipe_not_referenced() {128 %var = memref.alloc() : memref<f32>129 acc.parallel {130 %load = memref.load %var[] : memref<f32>131 acc.yield132 }133 memref.dealloc %var : memref<f32>134 return135}136 137// Global should NOT be acc declare'd because the recipe is not referenced138// CHECK-NOT: memref.global @global_for_private_unused {{.*}} {acc.declare139 140// -----141 142// Test globals in different compute constructs (parallel, kernels, serial)143 144memref.global @global_parallel : memref<f32> = dense<0.0>145memref.global @global_kernels : memref<f32> = dense<0.0>146memref.global constant @global_serial_const : memref<f32> = dense<1.0>147 148func.func @test_multiple_constructs() {149 acc.parallel {150 %addr = memref.get_global @global_parallel : memref<f32>151 %load = memref.load %addr[] : memref<f32>152 acc.yield153 }154 acc.kernels {155 %addr = memref.get_global @global_kernels : memref<f32>156 %load = memref.load %addr[] : memref<f32>157 acc.terminator158 }159 acc.serial {160 %addr = memref.get_global @global_serial_const : memref<f32>161 %load = memref.load %addr[] : memref<f32>162 acc.yield163 }164 return165}166 167// Non-constant globals ARE hoisted before their compute regions168// Constant global should be marked with acc.declare169// CHECK: memref.global constant @global_serial_const {{.*}} {acc.declare = #acc.declare<dataClause = acc_copyin>}170// CHECK-LABEL: func.func @test_multiple_constructs171// CHECK: memref.get_global @global_parallel172// CHECK-NEXT: acc.parallel173// CHECK: memref.get_global @global_kernels174// CHECK-NEXT: acc.kernels175 176