@@ -1115,32 +1115,35 @@ function replace_unreachable!(@nospecialize(job::CompilerJob), f::LLVM.Function)
11151115 # if we have multiple exit blocks, take the last one, which is hopefully the least
11161116 # divergent (assuming divergent control flow is the root of the problem here).
11171117 exit_block = last (exit_blocks)
1118-
11191118 ret = terminator (exit_block)
1120- if first (instructions (exit_block)) == ret
1119+
1120+ if first (instructions (exit_block)) == ret && isempty (operands (ret))
1121+ # if the exit block contains only `ret void`, we can branch to it directly.
11211122 return_block = exit_block
11221123 else
11231124 # split the exit block right before the ret, so that we only have to care about
11241125 # the value that's returned, and not about any other SSA value in the block.
11251126 return_block = BasicBlock (f, " ret" )
11261127 move_after (return_block, exit_block)
11271128
1128- # emit a return
1129+ # emit a branch
1130+ position! (builder, ret)
1131+ br! (builder, return_block)
1132+
1133+ # move the return
1134+ delete! (exit_block, ret)
11291135 position! (builder, return_block)
1130- if isempty (operands (ret))
1131- ret! (builder)
1132- else
1136+ insert! (builder, ret)
1137+
1138+ # if we're returning a value, insert a phi and update the return
1139+ if ! isempty (operands (ret))
1140+ position! (builder, ret)
11331141 # XXX : support aggregate returns?
11341142 val = only (operands (ret))
11351143 phi = phi! (builder, value_type (val))
11361144 push! (incoming (phi), (val, exit_block))
1137- ret! (builder, phi)
1145+ operands (ret)[ 1 ] = phi
11381146 end
1139-
1140- # replace with a branch
1141- position! (builder, ret)
1142- br! (builder, return_block)
1143- unsafe_delete! (exit_block, ret)
11441147 end
11451148
11461149 # replace the unreachable with a branch to the return block
0 commit comments