diff --git a/kotlin-native/backend.native/tests/build.gradle b/kotlin-native/backend.native/tests/build.gradle index 6c42a091a7e..7ca90dd5e96 100644 --- a/kotlin-native/backend.native/tests/build.gradle +++ b/kotlin-native/backend.native/tests/build.gradle @@ -5866,6 +5866,10 @@ fileCheckTest("filecheck_escape_analysis_disabled") { checkPrefix = "CHECK-DEBUG" } +fileCheckTest("filecheck_bce") { + annotatedSource = project.file('filecheck/bce.kt') +} + dependencies { nopPluginApi project(kotlinCompilerModule) nopPluginApi project(":native:kotlin-native-utils") diff --git a/kotlin-native/backend.native/tests/filecheck/bce.kt b/kotlin-native/backend.native/tests/filecheck/bce.kt new file mode 100644 index 00000000000..efc46cde4db --- /dev/null +++ b/kotlin-native/backend.native/tests/filecheck/bce.kt @@ -0,0 +1,224 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +// CHECK-LABEL: define void @"kfun:#forEachIndicies(){}"() +fun forEachIndicies() { + val array = Array(10) { 0 } + + // CHECK: {{^}}do_while_loop{{.*}}: + for (i in array.indices) { + // CHECK: invoke void @Kotlin_Array_set_without_BoundCheck + array[i] = 6 + } +} +// CHECK-LABEL: {{^}}epilogue: + +// CHECK-LABEL: define void @"kfun:#forUntilSize(){}"() +fun forUntilSize() { + val array = Array(10) { 0L } + // CHECK: {{^}}do_while_loop{{.*}}: + for (i in 0 until array.size) { + // CHECK: invoke void @Kotlin_Array_set_without_BoundCheck + array[i] = 6 + } +} +// CHECK-LABEL: {{^}}epilogue: + +// CHECK-LABEL: define void @"kfun:#forDownToSize(){}"() +fun forDownToSize() { + val array = Array(10) { 0L } + + // CHECK: {{^}}do_while_loop{{.*}}: + for (i in array.size - 1 downTo 0) { + // CHECK: invoke void @Kotlin_Array_set_without_BoundCheck + array[i] = 6 + } + + // CHECK: {{^}}do_while_loop{{.*}}: + for (j in array.size - 3 downTo 0) { + // CHECK: invoke void @Kotlin_Array_set_without_BoundCheck + array[j] = 6 + } +} +// CHECK-LABEL: {{^}}epilogue: + +// CHECK-LABEL: define void @"kfun:#forRangeToSize(){}"() +fun forRangeToSize() { + val array = Array(10) { 0L } + + // CHECK: {{^}}do_while_loop{{.*}}: + for (i in 0..array.size - 1) { + // CHECK: invoke void @Kotlin_Array_set_without_BoundCheck + array[i] = 6 + } + + val length = array.size - 1 + + // CHECK: {{^}}do_while_loop{{.*}}: + for (j in 0..length) { + // CHECK: invoke void @Kotlin_Array_set_without_BoundCheck + array[j] = 6 + } +} +// CHECK-LABEL: {{^}}epilogue: + +// CHECK-LABEL: define void @"kfun:#forRangeToWithStep(){}"() +fun forRangeToWithStep() { + val array = Array(10) { 0L } + + // CHECK: {{^}}do_while_loop{{.*}}: + for (i in 0..array.size - 1 step 2) { + // CHECK: invoke void @Kotlin_Array_set_without_BoundCheck + array[i] = 6 + } +} +// CHECK-LABEL: {{^}}epilogue: + +// CHECK-LABEL: define void @"kfun:#forUntilWithStep(){}"() +fun forUntilWithStep() { + val array = CharArray(10) { '0' } + // CHECK: {{^}}do_while_loop{{.*}}: + for (i in 0 until array.size step 2) { + // CHECK: invoke void @Kotlin_CharArray_set_without_BoundCheck + array[i] = '6' + } +} +// CHECK-LABEL: {{^}}epilogue: + +// CHECK-LABEL: define void @"kfun:#forDownToWithStep(){}"() +fun forDownToWithStep() { + val array = UIntArray(10) { 0U } + // CHECK: {{^}}do_while_loop{{.*}}: + for (i in array.size - 1 downTo 0 step 2) { + // CHECK: invoke void @Kotlin_IntArray_set_without_BoundCheck + array[i] = 6U + } +} +// CHECK-LABEL: {{^}}epilogue: + +// CHECK-LABEL: define void @"kfun:#forIndiciesWithStep(){}"() +fun forIndiciesWithStep() { + val array = Array(10) { 0L } + // CHECK: {{^}}do_while_loop{{.*}}: + for (i in array.indices step 2) { + // CHECK: invoke void @Kotlin_Array_set_without_BoundCheck + array[i] = 6 + } +} +// CHECK-LABEL: {{^}}epilogue: + +// CHECK-LABEL: define void @"kfun:#forWithIndex(){}"() +fun forWithIndex() { + val array = Array(10) { 100 } + + // CHECK: {{^}}while_loop{{.*}}: + for ((index, value) in array.withIndex()) { + // CHECK: invoke %struct.ObjHeader* @Kotlin_Array_get_without_BoundCheck + array[index] = 6 + } +} +// CHECK-LABEL: {{^}}epilogue: + +// CHECK-LABEL: define void @"kfun:#forReversed(){}"() +fun forReversed() { + val array = Array(10) { 100 } + // CHECK: {{^}}do_while_loop{{.*}}: + for (i in (0..array.size-1).reversed()) { + // CHECK: invoke void @Kotlin_Array_set_without_BoundCheck + array[i] = 6 + } +} +// CHECK-LABEL: {{^}}epilogue: + +fun foo(a: Int, b : Int): Int = a + b * 2 + +// CHECK-LABEL: define void @"kfun:#forEachCall(){}"() +fun forEachCall() { + val array = Array(10) { 100 } + var sum = 0 + // CHECK: {{^}}while_loop{{.*}}: + array.forEach { + // CHECK: invoke %struct.ObjHeader* @Kotlin_Array_get_without_BoundCheck + sum += it + } +} +// CHECK-LABEL: {{^}}epilogue: + +// CHECK-LABEL: define void @"kfun:#forLoop(){}"() +fun forLoop() { + val array = Array(10) { 100 } + var sum = 0 + // CHECK: {{^}}while_loop{{.*}}: + for (it in array) { + // CHECK: invoke %struct.ObjHeader* @Kotlin_Array_get_without_BoundCheck + sum += it + } +} +// CHECK-LABEL: {{^}}epilogue: + +// CHECK-LABEL: define void @"kfun:#innerLoop(){}"() +fun innerLoop() { + val array = Array(10) { 100 } + val array1 = Array(3) { 0 } + + // CHECK: {{^}}do_while_loop{{.*}}: + for (i in 0 until array.size) { + // CHECK-DAG: invoke %struct.ObjHeader* @Kotlin_Array_get_without_BoundCheck + array[i] = 7 + // CHECK-DAG: invoke void @Kotlin_Array_set_without_BoundCheck + // CHECK-DAG: invoke void @Kotlin_Array_set_without_BoundCheck + for (j in 0 until array1.size) { + array1[j] = array[i] + } + } +} +// CHECK-LABEL: {{^}}epilogue: + +// CHECK-LABEL: define void @"kfun:#argsInFunctionCall(){}"() +fun argsInFunctionCall() { + val array = Array(10) { 100 } + + val size = array.size - 1 + val size1 = size + + // CHECK: {{^}}do_while_loop{{.*}}: + for (i in 0..size1) { + // CHECK: invoke %struct.ObjHeader* @Kotlin_Array_get_without_BoundCheck + // CHECK: invoke %struct.ObjHeader* @Kotlin_Array_get_without_BoundCheck + // CHECK: invoke i32 @"kfun:#foo(kotlin.Int;kotlin.Int){}kotlin.Int" + foo(array[i], array[i]) + } +} +// CHECK-LABEL: {{^}}epilogue: + +// define void @"kfun:#smallLoop(){}"() +fun smallLoop() { + val array = Array(10) { 100 } + + // CHECK: {{^}}do_while_loop{{.*}}: + for (i in 0..array.size - 2) { + // CHECK: invoke %struct.ObjHeader* @Kotlin_Array_get_without_BoundCheck + array[i+1] = array[i] + } +} +// CHECK-LABEL: {{^}}epilogue: + +fun main() { + forEachIndicies() + forUntilSize() + forDownToSize() + forRangeToSize() + forRangeToWithStep() + forUntilWithStep() + forDownToWithStep() + forIndiciesWithStep() + forWithIndex() + forReversed() + forEachCall() + forLoop() + innerLoop() + argsInFunctionCall() + smallLoop() +} \ No newline at end of file