Skip to content

Inlining fails when there is no default branch #76772

Open
@dianqk

Description

@dianqk

From #76669 (comment).

In the following code, with the -O2 -inline-threshold=20 argument, bar1 will be inlined, but bar2 will not.
I expect that if bar1 will be inlined, bar2 should also be inlined. If bar2 is not inlined, bar1 should not be inlined either.

target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

define i64 @bar1(i64 %0) {
  %2 = and i64 %0, 6
  switch i64 %2, label %default_branch [
    i64 0, label %branch_0
    i64 2, label %branch_2
    i64 4, label %branch_4
  ]

branch_0:                                         ; preds = %1
  br label %exit

branch_2:                                         ; preds = %1
  br label %exit

branch_4:                                         ; preds = %1
  br label %exit

default_branch:                                   ; preds = %1
  br label %exit

exit:                                             ; preds = %default_branch, %branch_4, %branch_2, %branch_0
  %3 = phi i64 [ 5, %branch_0 ], [ 9, %branch_2 ], [ 2, %branch_4 ], [ 7, %default_branch ]
  ret i64 %3
}

define i64 @bar2(i64 %0) {
  %2 = and i64 %0, 6
  switch i64 %2, label %unreachabledefault [
    i64 0, label %branch_0
    i64 2, label %branch_2
    i64 4, label %branch_4
    i64 6, label %branch_6
  ]

branch_0:                                         ; preds = %1
  br label %exit

branch_2:                                         ; preds = %1
  br label %exit

branch_4:                                         ; preds = %1
  br label %exit

branch_6:                                         ; preds = %1
  br label %exit

unreachabledefault:                               ; preds = %1
  unreachable

exit:                                             ; preds = %branch_6, %branch_4, %branch_2, %branch_0
  %3 = phi i64 [ 5, %branch_0 ], [ 9, %branch_2 ], [ 2, %branch_4 ], [ 7, %branch_6 ]
  ret i64 %3
}

define i64 @foo1(i64 %0) {
  %2 = call i64 @bar1(i64 %0)
  ret i64 %2
}

define i64 @foo2(i64 %0) {
  %2 = call i64 @bar2(i64 %0)
  ret i64 %2
}

Generally, If a version with a default branch can be inlined, it should also get inlined without a default branch. I think a switch without a default branch generates fewer instructions.

cc @dtcxzyw

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions