Fix basic blocks order for WHEN expression
Merge-request: KT-MR-6833 Merged-by: Vladimir Sukharev <Vladimir.Sukharev@jetbrains.com>
This commit is contained in:
+50
-29
@@ -1283,12 +1283,16 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
||||
* }
|
||||
* we cannot determine if the result of when is assigned or not.
|
||||
*/
|
||||
private inner class WhenEmittingContext(val expression: IrWhen) {
|
||||
private inner class WhenEmittingContext(val expression: IrWhen, val lastBBOfWhenCases: LLVMBasicBlockRef) {
|
||||
val needsPhi = expression.branches.last().isUnconditional() && !expression.type.isUnit()
|
||||
val llvmType = codegen.getLLVMType(expression.type)
|
||||
|
||||
val bbExit = lazy { functionGenerationContext.basicBlock("when_exit", expression.endLocation) }
|
||||
|
||||
val bbExit = lazy {
|
||||
// bbExit must be positioned after all blocks of WHEN construct
|
||||
functionGenerationContext.appendingTo(lastBBOfWhenCases) {
|
||||
functionGenerationContext.basicBlock("when_exit", expression.endLocation)
|
||||
}
|
||||
}
|
||||
val resultPhi = lazy {
|
||||
functionGenerationContext.appendingTo(bbExit.value) {
|
||||
functionGenerationContext.phi(llvmType)
|
||||
@@ -1296,19 +1300,35 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
||||
}
|
||||
}
|
||||
|
||||
/** For WHEN { COND1 -> CASE1, COND2 -> CASE2, ELSE -> UNCONDITIONAL }
|
||||
* the following sequence of basic blocks is generated:
|
||||
* -- if COND1
|
||||
* -- CASE1
|
||||
* -- NEXT1(if COND2)
|
||||
* -- CASE2
|
||||
* -- NEXT2 (UNCONDITIONAL)
|
||||
* -- EXIT
|
||||
*/
|
||||
private fun evaluateWhen(expression: IrWhen, resultSlot: LLVMValueRef?): LLVMValueRef {
|
||||
context.log{"evaluateWhen : ${ir2string(expression)}"}
|
||||
|
||||
val whenEmittingContext = WhenEmittingContext(expression)
|
||||
|
||||
generateDebugTrambolineIf("when", expression)
|
||||
expression.branches.forEach {
|
||||
val bbNext = if (it == expression.branches.last())
|
||||
null
|
||||
else
|
||||
functionGenerationContext.basicBlock("when_next", it.startLocation, it.endLocation)
|
||||
generateWhenCase(whenEmittingContext, it, bbNext, resultSlot)
|
||||
|
||||
// First, generate all empty basic blocks for conditions and variants
|
||||
val bbOfFirstConditionCheck = functionGenerationContext.currentBlock
|
||||
val branchInfos: List<BranchCaseNextInfo> = expression.branches.map {
|
||||
// Carefully create empty basic blocks and position them one after another
|
||||
val bbCase = if (it.isUnconditional()) null else
|
||||
functionGenerationContext.basicBlock("when_case", it.startLocation, it.endLocation).apply { functionGenerationContext.positionAtEnd(this) }
|
||||
val bbNext = if (it.isUnconditional() || it == expression.branches.last()) null else
|
||||
functionGenerationContext.basicBlock("when_next", it.startLocation, it.endLocation).apply { functionGenerationContext.positionAtEnd(this) }
|
||||
BranchCaseNextInfo(it, bbCase, bbNext, resultSlot)
|
||||
}
|
||||
// Now, exit basic block can be positioned after all blocks of WHEN expression
|
||||
val whenEmittingContext = WhenEmittingContext(expression, lastBBOfWhenCases = functionGenerationContext.currentBlock)
|
||||
functionGenerationContext.positionAtEnd(bbOfFirstConditionCheck)
|
||||
|
||||
branchInfos.forEach { generateWhenCase(whenEmittingContext, it) }
|
||||
|
||||
if (whenEmittingContext.bbExit.isInitialized())
|
||||
functionGenerationContext.positionAtEnd(whenEmittingContext.bbExit.value)
|
||||
@@ -1330,25 +1350,26 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateWhenCase(whenEmittingContext: WhenEmittingContext, branch: IrBranch, bbNext: LLVMBasicBlockRef?, resultSlot: LLVMValueRef?) {
|
||||
val brResult = if (branch.isUnconditional())
|
||||
evaluateExpression(branch.result, resultSlot)
|
||||
else {
|
||||
val bbCase = functionGenerationContext.basicBlock("when_case", branch.startLocation, branch.endLocation)
|
||||
val condition = evaluateExpression(branch.condition)
|
||||
functionGenerationContext.condBr(condition, bbCase, bbNext ?: whenEmittingContext.bbExit.value)
|
||||
functionGenerationContext.positionAtEnd(bbCase)
|
||||
evaluateExpression(branch.result, resultSlot)
|
||||
}
|
||||
if (!functionGenerationContext.isAfterTerminator()) {
|
||||
if (whenEmittingContext.needsPhi)
|
||||
functionGenerationContext.assignPhis(whenEmittingContext.resultPhi.value to brResult)
|
||||
functionGenerationContext.br(whenEmittingContext.bbExit.value)
|
||||
}
|
||||
if (bbNext != null)
|
||||
functionGenerationContext.positionAtEnd(bbNext)
|
||||
}
|
||||
private data class BranchCaseNextInfo(val branch: IrBranch, val bbCase: LLVMBasicBlockRef?, val bbNext: LLVMBasicBlockRef?,
|
||||
val resultSlot: LLVMValueRef?)
|
||||
|
||||
private fun generateWhenCase(whenEmittingContext: WhenEmittingContext, branchCaseNextInfo: BranchCaseNextInfo) {
|
||||
with(branchCaseNextInfo) {
|
||||
if (!branch.isUnconditional()) {
|
||||
val condition = evaluateExpression(branch.condition)
|
||||
functionGenerationContext.condBr(condition, bbCase, bbNext ?: whenEmittingContext.bbExit.value)
|
||||
functionGenerationContext.positionAtEnd(bbCase!!)
|
||||
}
|
||||
val brResult = evaluateExpression(branch.result, resultSlot)
|
||||
if (!functionGenerationContext.isAfterTerminator()) {
|
||||
if (whenEmittingContext.needsPhi)
|
||||
functionGenerationContext.assignPhis(whenEmittingContext.resultPhi.value to brResult)
|
||||
functionGenerationContext.br(whenEmittingContext.bbExit.value)
|
||||
}
|
||||
if (bbNext != null)
|
||||
functionGenerationContext.positionAtEnd(bbNext)
|
||||
}
|
||||
}
|
||||
//-------------------------------------------------------------------------//
|
||||
|
||||
private fun evaluateWhileLoop(loop: IrWhileLoop): LLVMValueRef {
|
||||
|
||||
@@ -6151,6 +6151,10 @@ fileCheckTest("filecheck_smoke0") {
|
||||
annotatedSource = project.file('filecheck/smoke0.kt')
|
||||
}
|
||||
|
||||
fileCheckTest("filecheck_when") {
|
||||
annotatedSource = project.file('filecheck/when.kt')
|
||||
}
|
||||
|
||||
if (HostManager.@Companion.hostIsMac) {
|
||||
fileCheckTest("filecheck_force_arm_instruction_set") {
|
||||
enabled = enabled && cacheTesting == null
|
||||
|
||||
+16
-20
@@ -7,16 +7,14 @@ package codegen.stringConcatenationTypeNarrowing.kt53119_append_generated
|
||||
import kotlin.test.*
|
||||
|
||||
// CHECK-LABEL: define %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_append_generated#maybeAnyMaybeAny
|
||||
// CHECK: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append(kotlin.String?)
|
||||
// CHECK: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append(kotlin.String)
|
||||
// CHECK: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append(kotlin.String?)
|
||||
// CHECK-NOT: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append
|
||||
|
||||
// CHECK: %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_append_generated.Foo#toString(){}kotlin.String"
|
||||
// CHECK-NOT: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append
|
||||
|
||||
// CHECK: %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_append_generated.Foo#toString(){}kotlin.String"
|
||||
// CHECK-NOT: Foo#toString(){}kotlin.String"
|
||||
// CHECK: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append(kotlin.String?)
|
||||
// CHECK: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append(kotlin.String)
|
||||
// CHECK-NOT: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append
|
||||
|
||||
// CHECK: %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_append_generated.Foo#toString(){}kotlin.String"
|
||||
// CHECK: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append(kotlin.String?)
|
||||
// CHECK-NOT: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append
|
||||
|
||||
// CHECK: ret %struct.ObjHeader*
|
||||
@@ -26,14 +24,13 @@ fun maybeAnyMaybeAny(maybeAny1: Any?, maybeAny2: Any?): String {
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_append_generated#maybeAnyMaybeString
|
||||
// CHECK: %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_append_generated.Foo#toString(){}kotlin.String"
|
||||
// CHECK-NOT: Foo#toString(){}kotlin.String"
|
||||
// CHECK: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append(kotlin.String?)
|
||||
// CHECK: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append(kotlin.String)
|
||||
// CHECK: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append(kotlin.String?)
|
||||
// CHECK-NOT: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append
|
||||
|
||||
// CHECK: %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_append_generated.Foo#toString(){}kotlin.String"
|
||||
// CHECK-NOT: Foo#toString(){}kotlin.String"
|
||||
|
||||
// CHECK-NOT: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append
|
||||
// CHECK: ret %struct.ObjHeader*
|
||||
|
||||
@@ -42,14 +39,13 @@ fun maybeAnyMaybeString(maybeAny1: Any?, maybeString2: String?): String {
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_append_generated#maybeAnyString
|
||||
// CHECK: %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_append_generated.Foo#toString(){}kotlin.String"
|
||||
// CHECK-NOT: Foo#toString(){}kotlin.String"
|
||||
// CHECK: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append(kotlin.String?)
|
||||
// CHECK: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append(kotlin.String)
|
||||
// CHECK: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append(kotlin.String)
|
||||
// CHECK-NOT: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append
|
||||
|
||||
// CHECK: %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_append_generated.Foo#toString(){}kotlin.String"
|
||||
// CHECK-NOT: Foo#toString(){}kotlin.String"
|
||||
|
||||
// CHECK-NOT: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append
|
||||
// CHECK: ret %struct.ObjHeader*
|
||||
|
||||
@@ -60,6 +56,8 @@ fun maybeAnyString(maybeAny1: Any?, string: String): String {
|
||||
data class Foo(val bar: Int)
|
||||
|
||||
// CHECK-LABEL: define %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_append_generated#maybeAnyFoo
|
||||
// CHECK: %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_append_generated.Foo#toString(){}kotlin.String"
|
||||
// CHECK-NOT: Foo#toString(){}kotlin.String"
|
||||
// CHECK: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append(kotlin.String?)
|
||||
// CHECK: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append(kotlin.String)
|
||||
// CHECK-NOT: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append
|
||||
@@ -68,9 +66,6 @@ data class Foo(val bar: Int)
|
||||
// CHECK: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append(kotlin.String?)
|
||||
// CHECK-NOT: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append
|
||||
|
||||
// CHECK: %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_append_generated.Foo#toString(){}kotlin.String"
|
||||
// CHECK-NOT: Foo#toString(){}kotlin.String"
|
||||
|
||||
// CHECK-NOT: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append
|
||||
// CHECK: ret %struct.ObjHeader*
|
||||
|
||||
@@ -78,14 +73,15 @@ fun maybeAnyFoo(maybeAny: Any?, foo: Foo): String {
|
||||
return "$maybeAny,$foo"
|
||||
}
|
||||
// CHECK-LABEL: define %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_append_generated#maybeAnyMaybeFoo
|
||||
// CHECK: %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_append_generated.Foo#toString(){}kotlin.String"
|
||||
// CHECK-NOT: Foo#toString(){}kotlin.String"
|
||||
// CHECK: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append(kotlin.String?)
|
||||
// CHECK: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append(kotlin.String)
|
||||
// CHECK: %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_append_generated.Foo#toString(){}kotlin.String"
|
||||
// CHECK-NOT: Foo#toString(){}kotlin.String"
|
||||
// CHECK: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append(kotlin.String?)
|
||||
// CHECK-NOT: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append
|
||||
|
||||
// CHECK: %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_append_generated.Foo#toString(){}kotlin.String"
|
||||
// CHECK: %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_append_generated.Foo#toString(){}kotlin.String"
|
||||
// CHECK-NOT: Foo#toString(){}kotlin.String"
|
||||
|
||||
// CHECK-NOT: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append
|
||||
// CHECK: ret %struct.ObjHeader*
|
||||
|
||||
+1
-3
@@ -7,11 +7,9 @@ package codegen.stringConcatenationTypeNarrowing.kt53119_append_manual
|
||||
import kotlin.test.*
|
||||
|
||||
// CHECK-LABEL: define %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_append_manual#appendMaybeAny(kotlin.Any?)
|
||||
// CHECK: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append(kotlin.String?)
|
||||
// CHECK-NOT: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append
|
||||
|
||||
// CHECK: %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_append_manual.Foo#toString(){}kotlin.String"
|
||||
// CHECK-NOT: Foo#toString(){}kotlin.String"
|
||||
// CHECK: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append(kotlin.String?)
|
||||
// CHECK-NOT: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append
|
||||
|
||||
// CHECK: ret %struct.ObjHeader*
|
||||
|
||||
+7
-15
@@ -9,17 +9,15 @@ import kotlin.test.*
|
||||
// CHECK-LABEL: define %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_plus_extension#manualPlusExtensionAny
|
||||
// CHECK-NOT: kfun:kotlin.String#plus(kotlin.Any?)
|
||||
|
||||
// CHECK: call %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_plus_extension.Foo#toString(){}kotlin.String"
|
||||
// CHECK-NOT: Foo#toString(){}kotlin.String"
|
||||
|
||||
// CHECK: call %struct.ObjHeader* @Kotlin_String_plusImpl
|
||||
// CHECK-NOT: call %struct.ObjHeader* @Kotlin_String_plusImpl
|
||||
// CHECK-NOT: kfun:kotlin.String#plus(kotlin.Any?)
|
||||
// CHECK-NOT: call %struct.ObjHeader* @"kfun:kotlin.String#toString(){}kotlin.String"
|
||||
|
||||
// CHECK: call %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_plus_extension.Foo#toString(){}kotlin.String"
|
||||
|
||||
// CHECK-NOT: call %struct.ObjHeader* @"kfun:kotlin.String#toString(){}kotlin.String"
|
||||
// CHECK-NOT: Foo#toString(){}kotlin.String"
|
||||
// CHECK-NOT: call %struct.ObjHeader* @Kotlin_String_plusImpl
|
||||
// CHECK-NOT: kfun:kotlin.String#plus(kotlin.Any?)
|
||||
|
||||
// CHECK: ret %struct.ObjHeader*
|
||||
|
||||
@@ -43,16 +41,12 @@ fun manualPlusExtensionString(maybeStr: String?, str: String): kotlin.String =
|
||||
// CHECK-LABEL: define %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_plus_extension#generatedPlusExtensionAny
|
||||
// CHECK-NOT: kfun:kotlin#plus__at__kotlin.String?(kotlin.Any?)
|
||||
|
||||
// CHECK: call %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_plus_extension.Foo#toString(){}kotlin.String"
|
||||
// CHECK-NOT: Foo#toString(){}kotlin.String"
|
||||
// CHECK: call %struct.ObjHeader* @Kotlin_String_plusImpl
|
||||
// CHECK-NOT: call %struct.ObjHeader* @Kotlin_String_plusImpl
|
||||
// CHECK-NOT: kfun:kotlin#plus__at__kotlin.String?(kotlin.Any?)
|
||||
|
||||
// CHECK: call %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_plus_extension.Foo#toString(){}kotlin.String"
|
||||
|
||||
// CHECK-NOT: Foo#toString(){}kotlin.String"
|
||||
// CHECK-NOT: call %struct.ObjHeader* @"kfun:kotlin.String#toString(){}kotlin.String"
|
||||
// CHECK-NOT: kfun:kotlin#plus__at__kotlin.String?(kotlin.Any?)
|
||||
// CHECK-NOT: call %struct.ObjHeader* @Kotlin_String_plusImpl
|
||||
|
||||
// CHECK: ret %struct.ObjHeader*
|
||||
|
||||
@@ -98,14 +92,12 @@ fun generatedPlusExtensionFoo(maybeStr: String?, foo: Foo): String {
|
||||
// CHECK-LABEL: define %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_plus_extension#generatedPlusExtensionMaybeFoo
|
||||
// CHECK-NOT: kfun:kotlin.String#plus(kotlin.Any?)
|
||||
|
||||
// CHECK: call %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_plus_extension.Foo#toString(){}kotlin.String"
|
||||
// CHECK-NOT: Foo#toString(){}kotlin.String
|
||||
// CHECK: call %struct.ObjHeader* @Kotlin_String_plusImpl
|
||||
// CHECK-NOT: call %struct.ObjHeader* @Kotlin_String_plusImpl
|
||||
// CHECK-NOT: call %struct.ObjHeader* @"kfun:kotlin.String#toString(){}kotlin.String"
|
||||
|
||||
// CHECK: call %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_plus_extension.Foo#toString(){}kotlin.String"
|
||||
// CHECK-NOT: Foo#toString(){}kotlin.String
|
||||
|
||||
// CHECK-NOT: call %struct.ObjHeader* @"kfun:kotlin.String#toString(){}kotlin.String"
|
||||
// CHECK-NOT: kfun:kotlin.String#plus(kotlin.Any?)
|
||||
|
||||
// CHECK: ret %struct.ObjHeader*
|
||||
|
||||
+4
-8
@@ -9,11 +9,9 @@ import kotlin.test.*
|
||||
// CHECK-LABEL: define %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_plus_member#manualPlusMemberAny
|
||||
// CHECK-NOT: kfun:kotlin.String#plus(kotlin.Any?)
|
||||
|
||||
// CHECK: call %struct.ObjHeader* @Kotlin_String_plusImpl
|
||||
// CHECK-NOT: kfun:kotlin.String#plus(kotlin.Any?)
|
||||
|
||||
// CHECK: call %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_plus_member.Foo#toString(){}kotlin.String"
|
||||
// CHECK-NOT: Foo#toString(){}kotlin.String"
|
||||
// CHECK: call %struct.ObjHeader* @Kotlin_String_plusImpl
|
||||
// CHECK-NOT: kfun:kotlin.String#plus(kotlin.Any?)
|
||||
|
||||
// CHECK: ret %struct.ObjHeader*
|
||||
@@ -37,12 +35,9 @@ fun manualPlusMemberString(str1: String, str2: String): kotlin.String =
|
||||
// CHECK-LABEL: define %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_plus_member#generatedPlusMemberAny
|
||||
// CHECK-NOT: kfun:kotlin.String#plus(kotlin.Any?)
|
||||
|
||||
// CHECK: call %struct.ObjHeader* @Kotlin_String_plusImpl
|
||||
// CHECK-NOT: kfun:kotlin.String#plus(kotlin.Any?)
|
||||
|
||||
// CHECK: call %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_plus_member.Foo#toString(){}kotlin.String"
|
||||
// CHECK-NOT: Foo#toString(){}kotlin.String"
|
||||
|
||||
// CHECK: call %struct.ObjHeader* @Kotlin_String_plusImpl
|
||||
// CHECK-NOT: kfun:kotlin.String#plus(kotlin.Any?)
|
||||
|
||||
// CHECK: ret %struct.ObjHeader*
|
||||
@@ -86,9 +81,10 @@ fun manualPlusMemberFoo(str1: String, foo: Foo): kotlin.String =
|
||||
// CHECK call %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_plus_member.Foo#toString(){}kotlin.String"
|
||||
// CHECK-NOT Foo#toString(){}kotlin.String
|
||||
|
||||
// CHECK: call %struct.ObjHeader* @Kotlin_String_plusImpl
|
||||
// CHECK: call %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_plus_member.Foo#toString
|
||||
// CHECK-NOT: Foo#toString(){}kotlin.String"
|
||||
// CHECK-NOT: kfun:kotlin.String#plus(kotlin.Any?)
|
||||
// CHECK: call %struct.ObjHeader* @Kotlin_String_plusImpl
|
||||
// CHECK-NOT: Foo#toString(){}kotlin.String"
|
||||
|
||||
// CHECK: ret %struct.ObjHeader*
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright 2010-2022 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.
|
||||
*/
|
||||
|
||||
var i = 1
|
||||
fun main() {
|
||||
println(when(i) {
|
||||
0 -> 10
|
||||
1 -> 11
|
||||
2 -> 12
|
||||
else -> 13
|
||||
})
|
||||
}
|
||||
// CHECK-LABEL: define void @"kfun:#main(){}"()
|
||||
// CHECK: when_case
|
||||
// CHECK: when_next
|
||||
// CHECK: when_case1
|
||||
// CHECK: when_next2
|
||||
// CHECK: when_case3
|
||||
// CHECK: when_next4
|
||||
// CHECK: when_exit
|
||||
// CHECK: call void @"kfun:kotlin.io#println(kotlin.Any?)
|
||||
// CHECK: ret void
|
||||
Reference in New Issue
Block a user