1// RUN: mlir-translate -mlir-to-llvmir -split-input-file %s | FileCheck %s 2 3// CHECK-LABEL: @disableNonForced 4llvm.func @disableNonForced() { 5 // CHECK: br {{.*}} !llvm.loop ![[LOOP_NODE:[0-9]+]] 6 llvm.br ^bb1 {loop_annotation = #llvm.loop_annotation<disableNonforced = true>} 7^bb1: 8 llvm.return 9} 10 11// CHECK: ![[LOOP_NODE]] = distinct !{![[LOOP_NODE]], !{{[0-9]+}}} 12// CHECK-DAG: ![[VEC_NODE0:[0-9]+]] = !{!"llvm.loop.disable_nonforced"} 13 14// ----- 15 16// CHECK-LABEL: @mustprogress 17llvm.func @mustprogress() { 18 // CHECK: br {{.*}} !llvm.loop ![[LOOP_NODE:[0-9]+]] 19 llvm.br ^bb1 {loop_annotation = #llvm.loop_annotation<mustProgress = true>} 20^bb1: 21 llvm.return 22} 23 24// CHECK: ![[LOOP_NODE]] = distinct !{![[LOOP_NODE]], !{{[0-9]+}}} 25// CHECK-DAG: ![[VEC_NODE0:[0-9]+]] = !{!"llvm.loop.mustprogress"} 26 27// ----- 28 29// CHECK-LABEL: @isvectorized 30llvm.func @isvectorized() { 31 // CHECK: br {{.*}} !llvm.loop ![[LOOP_NODE:[0-9]+]] 32 llvm.br ^bb1 {loop_annotation = #llvm.loop_annotation<isVectorized = true>} 33^bb1: 34 llvm.return 35} 36 37// CHECK: ![[LOOP_NODE]] = distinct !{![[LOOP_NODE]], !{{[0-9]+}}} 38// CHECK-DAG: ![[VEC_NODE0:[0-9]+]] = !{!"llvm.loop.isvectorized", i32 1} 39 40// ----- 41 42#followup = #llvm.loop_annotation<disableNonforced = true> 43 44// CHECK-LABEL: @vectorizeOptions 45llvm.func @vectorizeOptions() { 46 // CHECK: br {{.*}} !llvm.loop ![[LOOP_NODE:[0-9]+]] 47 llvm.br ^bb1 {loop_annotation = #llvm.loop_annotation<vectorize = < 48 disable = false, predicateEnable = true, scalableEnable = false, width = 16 : i32, 49 followupVectorized = #followup, followupEpilogue = #followup, followupAll = #followup> 50 >} 51^bb1: 52 llvm.return 53} 54 55// CHECK-DAG: ![[NON_FORCED:[0-9]+]] = !{!"llvm.loop.disable_nonforced"} 56// CHECK-DAG: ![[FOLLOWUP:[0-9]+]] = distinct !{![[FOLLOWUP]], ![[NON_FORCED]]} 57// CHECK-DAG: ![[LOOP_NODE]] = distinct !{![[LOOP_NODE]], !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}} 58// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.vectorize.enable", i1 true} 59// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.vectorize.predicate.enable", i1 true} 60// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.vectorize.scalable.enable", i1 false} 61// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.vectorize.width", i32 16} 62// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.vectorize.followup_vectorized", ![[FOLLOWUP]]} 63// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.vectorize.followup_epilogue", ![[FOLLOWUP]]} 64// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.vectorize.followup_all", ![[FOLLOWUP]]} 65 66// ----- 67 68// CHECK-LABEL: @interleaveOptions 69llvm.func @interleaveOptions() { 70 // CHECK: br {{.*}} !llvm.loop ![[LOOP_NODE:[0-9]+]] 71 llvm.br ^bb1 {loop_annotation = #llvm.loop_annotation<interleave = <count = 32 : i32>>} 72^bb1: 73 llvm.return 74} 75 76// CHECK: ![[LOOP_NODE]] = distinct !{![[LOOP_NODE]], ![[INTERLEAVE_NODE:[0-9]+]]} 77// CHECK: ![[INTERLEAVE_NODE]] = !{!"llvm.loop.interleave.count", i32 32} 78 79// ----- 80 81#followup = #llvm.loop_annotation<disableNonforced = true> 82 83// CHECK-LABEL: @unrollOptions 84llvm.func @unrollOptions() { 85 // CHECK: br {{.*}} !llvm.loop ![[LOOP_NODE:[0-9]+]] 86 llvm.br ^bb1 {loop_annotation = #llvm.loop_annotation<unroll = < 87 disable = true, count = 64 : i32, runtimeDisable = false, full = false, 88 followupUnrolled = #followup, followupRemainder = #followup, followupAll = #followup> 89 >} 90^bb1: 91 llvm.return 92} 93 94// CHECK-DAG: ![[NON_FORCED:[0-9]+]] = !{!"llvm.loop.disable_nonforced"} 95// CHECK-DAG: ![[FOLLOWUP:[0-9]+]] = distinct !{![[FOLLOWUP]], ![[NON_FORCED]]} 96// CHECK-DAG: ![[LOOP_NODE]] = distinct !{![[LOOP_NODE]], !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}} 97// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.unroll.disable"} 98// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.unroll.count", i32 64} 99// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.unroll.runtime.disable", i1 false} 100// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.unroll.followup_unrolled", ![[FOLLOWUP]]} 101// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.unroll.followup_remainder", ![[FOLLOWUP]]} 102// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.unroll.followup_all", ![[FOLLOWUP]]} 103 104// ----- 105 106// CHECK-LABEL: @unrollOptions2 107llvm.func @unrollOptions2() { 108 // CHECK: br {{.*}} !llvm.loop ![[LOOP_NODE:[0-9]+]] 109 llvm.br ^bb1 {loop_annotation = #llvm.loop_annotation<unroll = <disable = false, full = true>>} 110^bb1: 111 llvm.return 112} 113 114// CHECK: ![[LOOP_NODE]] = distinct !{![[LOOP_NODE]], !{{[0-9]+}}, !{{[0-9]+}}} 115// CHECK-DAG: ![[VEC_NODE0:[0-9]+]] = !{!"llvm.loop.unroll.enable"} 116// CHECK-DAG: ![[VEC_NODE2:[0-9]+]] = !{!"llvm.loop.unroll.full"} 117 118// ----- 119 120#followup = #llvm.loop_annotation<disableNonforced = true> 121 122// CHECK-LABEL: @unrollAndJamOptions 123llvm.func @unrollAndJamOptions() { 124 // CHECK: br {{.*}} !llvm.loop ![[LOOP_NODE:[0-9]+]] 125 llvm.br ^bb1 {loop_annotation = #llvm.loop_annotation<unrollAndJam = < 126 disable = false, count = 8 : i32, followupOuter = #followup, followupInner = #followup, 127 followupRemainderOuter = #followup, followupRemainderInner = #followup, followupAll = #followup> 128 >} 129^bb1: 130 llvm.return 131} 132 133// CHECK-DAG: ![[NON_FORCED:[0-9]+]] = !{!"llvm.loop.disable_nonforced"} 134// CHECK-DAG: ![[FOLLOWUP:[0-9]+]] = distinct !{![[FOLLOWUP]], ![[NON_FORCED]]} 135// CHECK-DAG: ![[LOOP_NODE]] = distinct !{![[LOOP_NODE]], !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}} 136// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.unroll_and_jam.enable"} 137// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.unroll_and_jam.count", i32 8} 138// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.unroll_and_jam.followup_outer", ![[FOLLOWUP]]} 139// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.unroll_and_jam.followup_inner", ![[FOLLOWUP]]} 140// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.unroll_and_jam.followup_remainder_outer", ![[FOLLOWUP]]} 141// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.unroll_and_jam.followup_remainder_inner", ![[FOLLOWUP]]} 142// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.unroll_and_jam.followup_all", ![[FOLLOWUP]]} 143 144// ----- 145 146// CHECK-LABEL: @licmOptions 147llvm.func @licmOptions() { 148 // CHECK: br {{.*}} !llvm.loop ![[LOOP_NODE:[0-9]+]] 149 llvm.br ^bb1 {loop_annotation = #llvm.loop_annotation<licm = <disable = false, versioningDisable = true>>} 150^bb1: 151 llvm.return 152} 153 154// CHECK: ![[LOOP_NODE]] = distinct !{![[LOOP_NODE]], !{{[0-9]+}}} 155// CHECK-DAG: ![[VEC_NODE0:[0-9]+]] = !{!"llvm.loop.licm_versioning.disable"} 156 157// ----- 158 159// CHECK-LABEL: @licmOptions2 160llvm.func @licmOptions2() { 161 // CHECK: br {{.*}} !llvm.loop ![[LOOP_NODE:[0-9]+]] 162 llvm.br ^bb1 {loop_annotation = #llvm.loop_annotation<licm = <disable = true, versioningDisable = false>>} 163^bb1: 164 llvm.return 165} 166 167// CHECK: ![[LOOP_NODE]] = distinct !{![[LOOP_NODE]], !{{[0-9]+}}} 168// CHECK-DAG: ![[VEC_NODE0:[0-9]+]] = !{!"llvm.licm.disable"} 169 170// ----- 171 172#followup = #llvm.loop_annotation<disableNonforced = true> 173 174// CHECK-LABEL: @distributeOptions 175llvm.func @distributeOptions() { 176 // CHECK: br {{.*}} !llvm.loop ![[LOOP_NODE:[0-9]+]] 177 llvm.br ^bb1 {loop_annotation = #llvm.loop_annotation<distribute = < 178 disable = true, followupCoincident = #followup, followupSequential = #followup, 179 followupFallback = #followup, followupAll = #followup> 180 >} 181^bb1: 182 llvm.return 183} 184 185// CHECK-DAG: ![[NON_FORCED:[0-9]+]] = !{!"llvm.loop.disable_nonforced"} 186// CHECK-DAG: ![[FOLLOWUP:[0-9]+]] = distinct !{![[FOLLOWUP]], ![[NON_FORCED]]} 187// CHECK-DAG: ![[LOOP_NODE]] = distinct !{![[LOOP_NODE]], !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}} 188// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.distribute.enable", i1 false} 189// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.distribute.followup_coincident", ![[FOLLOWUP]]} 190// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.distribute.followup_sequential", ![[FOLLOWUP]]} 191// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.distribute.followup_fallback", ![[FOLLOWUP]]} 192// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.distribute.followup_all", ![[FOLLOWUP]]} 193 194// ----- 195 196// CHECK-LABEL: @pipelineOptions 197llvm.func @pipelineOptions() { 198 // CHECK: br {{.*}} !llvm.loop ![[LOOP_NODE:[0-9]+]] 199 llvm.br ^bb1 {loop_annotation = #llvm.loop_annotation<pipeline = <disable = false, initiationinterval = 1 : i32>>} 200^bb1: 201 llvm.return 202} 203 204// CHECK: ![[LOOP_NODE]] = distinct !{![[LOOP_NODE]], !{{[0-9]+}}, !{{[0-9]+}}} 205// CHECK-DAG: ![[VEC_NODE0:[0-9]+]] = !{!"llvm.loop.pipeline.disable", i1 false} 206// CHECK-DAG: ![[VEC_NODE0:[0-9]+]] = !{!"llvm.loop.pipeline.initiationinterval", i32 1} 207 208// ----- 209 210// CHECK-LABEL: @peeledOptions 211llvm.func @peeledOptions() { 212 // CHECK: br {{.*}} !llvm.loop ![[LOOP_NODE:[0-9]+]] 213 llvm.br ^bb1 {loop_annotation = #llvm.loop_annotation<peeled = <count = 3 : i32>>} 214^bb1: 215 llvm.return 216} 217 218// CHECK: ![[LOOP_NODE]] = distinct !{![[LOOP_NODE]], !{{[0-9]+}}} 219// CHECK-DAG: ![[VEC_NODE0:[0-9]+]] = !{!"llvm.loop.peeled.count", i32 3} 220 221// ----- 222 223// CHECK-LABEL: @unswitchOptions 224llvm.func @unswitchOptions() { 225 // CHECK: br {{.*}} !llvm.loop ![[LOOP_NODE:[0-9]+]] 226 llvm.br ^bb1 {loop_annotation = #llvm.loop_annotation<unswitch = <partialDisable = true>>} 227^bb1: 228 llvm.return 229} 230 231// CHECK: ![[LOOP_NODE]] = distinct !{![[LOOP_NODE]], !{{[0-9]+}}} 232// CHECK-DAG: ![[VEC_NODE0:[0-9]+]] = !{!"llvm.loop.unswitch.partial.disable"} 233 234// ----- 235 236llvm.func @foo(%arg0: i32) 237 238#group1 = #llvm.access_group<id = distinct[0]<>> 239#group2 = #llvm.access_group<id = distinct[1]<>> 240 241// CHECK-LABEL: @loopOptions 242llvm.func @loopOptions(%arg1 : i32, %arg2 : i32) { 243 %0 = llvm.mlir.constant(0 : i32) : i32 244 %4 = llvm.alloca %arg1 x i32 : (i32) -> (!llvm.ptr) 245 llvm.br ^bb3(%0 : i32) 246 ^bb3(%1: i32): 247 %2 = llvm.icmp "slt" %1, %arg1 : i32 248 // CHECK: br i1 {{.*}} !llvm.loop ![[LOOP_NODE:[0-9]+]] 249 llvm.cond_br %2, ^bb4, ^bb5 {loop_annotation = #llvm.loop_annotation< 250 licm = <disable = true>, 251 interleave = <count = 1>, 252 unroll = <disable = true>, pipeline = <disable = true, initiationinterval = 2>, 253 parallelAccesses = #group1, #group2>} 254 ^bb4: 255 %3 = llvm.add %1, %arg2 : i32 256 // CHECK: = load i32, ptr %{{.*}} !llvm.access.group ![[ACCESS_GROUPS_NODE:[0-9]+]] 257 %5 = llvm.load %4 {access_groups = [#group1, #group2]} : !llvm.ptr -> i32 258 // CHECK: store i32 %{{.*}}, ptr %{{.*}} !llvm.access.group ![[ACCESS_GROUPS_NODE]] 259 llvm.store %5, %4 {access_groups = [#group1, #group2]} : i32, !llvm.ptr 260 // CHECK: = atomicrmw add ptr %{{.*}}, i32 %{{.*}} !llvm.access.group ![[ACCESS_GROUPS_NODE]] 261 %6 = llvm.atomicrmw add %4, %5 monotonic {access_groups = [#group1, #group2]} : !llvm.ptr, i32 262 // CHECK: = cmpxchg ptr %{{.*}}, i32 %{{.*}}, i32 %{{.*}} !llvm.access.group ![[ACCESS_GROUPS_NODE]] 263 %7 = llvm.cmpxchg %4, %5, %6 acq_rel monotonic {access_groups = [#group1, #group2]} : !llvm.ptr, i32 264 %9 = llvm.mlir.constant(42 : i8) : i8 265 // CHECK: llvm.memcpy{{.*}} !llvm.access.group ![[ACCESS_GROUPS_NODE]] 266 "llvm.intr.memcpy"(%4, %4, %0) <{isVolatile = false}> {access_groups = [#group1, #group2]} : (!llvm.ptr, !llvm.ptr, i32) -> () 267 // CHECK: llvm.memset{{.*}} !llvm.access.group ![[ACCESS_GROUPS_NODE]] 268 "llvm.intr.memset"(%4, %9, %0) <{isVolatile = false}> {access_groups = [#group1, #group2]} : (!llvm.ptr, i8, i32) -> () 269 // CHECK: call void @foo({{.*}} !llvm.access.group ![[ACCESS_GROUPS_NODE]] 270 llvm.call @foo(%arg1) {access_groups = [#group1, #group2]} : (i32) -> () 271 // CHECK: br label {{.*}} !llvm.loop ![[LOOP_NODE]] 272 llvm.br ^bb3(%3 : i32) {loop_annotation = #llvm.loop_annotation< 273 licm = <disable = true>, 274 interleave = <count = 1>, 275 unroll = <disable = true>, pipeline = <disable = true, initiationinterval = 2>, 276 parallelAccesses = #group1, #group2>} 277 278 ^bb5: 279 llvm.return 280} 281 282// CHECK: ![[LOOP_NODE]] = distinct !{![[LOOP_NODE]], !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}} 283// CHECK-DAG: ![[PA_NODE:[0-9]+]] = !{!"llvm.loop.parallel_accesses", ![[GROUP_NODE1:[0-9]+]], ![[GROUP_NODE2:[0-9]+]]} 284// CHECK-DAG: ![[GROUP_NODE1:[0-9]+]] = distinct !{} 285// CHECK-DAG: ![[GROUP_NODE2:[0-9]+]] = distinct !{} 286// CHECK-DAG: ![[UNROLL_DISABLE_NODE:[0-9]+]] = !{!"llvm.loop.unroll.disable"} 287// CHECK-DAG: ![[LICM_DISABLE_NODE:[0-9]+]] = !{!"llvm.licm.disable"} 288// CHECK-DAG: ![[INTERLEAVE_NODE:[0-9]+]] = !{!"llvm.loop.interleave.count", i32 1} 289// CHECK-DAG: ![[PIPELINE_DISABLE_NODE:[0-9]+]] = !{!"llvm.loop.pipeline.disable", i1 true} 290// CHECK-DAG: ![[II_NODE:[0-9]+]] = !{!"llvm.loop.pipeline.initiationinterval", i32 2} 291// CHECK-DAG: ![[ACCESS_GROUPS_NODE:[0-9]+]] = !{![[GROUP_NODE1]], ![[GROUP_NODE2]]} 292 293// ----- 294 295#di_file = #llvm.di_file<"metadata-loop.ll" in "/"> 296 297#loc1 = loc("loop-metadata.mlir":42:4) 298#loc2 = loc("loop-metadata.mlir":52:4) 299 300#di_compile_unit = #llvm.di_compile_unit<id = distinct[0]<>, sourceLanguage = DW_LANG_C, file = #di_file, isOptimized = false, emissionKind = None> 301#di_subprogram = #llvm.di_subprogram<compileUnit = #di_compile_unit, scope = #di_file, name = "loop_locs", file = #di_file, subprogramFlags = Definition> 302 303#start_loc_fused = loc(fused<#di_subprogram>[#loc1]) 304#end_loc_fused= loc(fused<#di_subprogram>[#loc2]) 305 306#loopMD = #llvm.loop_annotation<disableNonforced = false, 307 startLoc = #start_loc_fused, 308 endLoc = #end_loc_fused> 309 310// CHECK-LABEL: @loop_annotation_with_locs 311llvm.func @loop_annotation_with_locs() { 312// CHECK: br {{.*}} !llvm.loop ![[LOOP_NODE:[0-9]+]] 313 llvm.br ^bb1 {loop_annotation = #loopMD} 314^bb1: 315 llvm.return 316} 317 318// CHECK: ![[LOOP_NODE]] = distinct !{![[LOOP_NODE]], ![[START_LOC:.*]], ![[END_LOC:.*]]} 319// CHECK: ![[START_LOC]] = !DILocation(line: 42, column: 4, scope: 320// CHECK: ![[END_LOC]] = !DILocation(line: 52, column: 4, scope: 321