@@ -1115,32 +1115,35 @@ function replace_unreachable!(@nospecialize(job::CompilerJob), f::LLVM.Function)
1115
1115
# if we have multiple exit blocks, take the last one, which is hopefully the least
1116
1116
# divergent (assuming divergent control flow is the root of the problem here).
1117
1117
exit_block = last (exit_blocks)
1118
-
1119
1118
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.
1121
1122
return_block = exit_block
1122
1123
else
1123
1124
# split the exit block right before the ret, so that we only have to care about
1124
1125
# the value that's returned, and not about any other SSA value in the block.
1125
1126
return_block = BasicBlock (f, " ret" )
1126
1127
move_after (return_block, exit_block)
1127
1128
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)
1129
1135
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)
1133
1141
# XXX : support aggregate returns?
1134
1142
val = only (operands (ret))
1135
1143
phi = phi! (builder, value_type (val))
1136
1144
push! (incoming (phi), (val, exit_block))
1137
- ret! (builder, phi)
1145
+ operands (ret)[ 1 ] = phi
1138
1146
end
1139
-
1140
- # replace with a branch
1141
- position! (builder, ret)
1142
- br! (builder, return_block)
1143
- unsafe_delete! (exit_block, ret)
1144
1147
end
1145
1148
1146
1149
# replace the unreachable with a branch to the return block
0 commit comments