Skip to content

Commit

Permalink
Abort cmov optimization, when one of the out blocks is try block (dot…
Browse files Browse the repository at this point in the history
…net#2373)

Fixes mono/mono#17733

Co-authored-by: Fan Yang <[email protected]>
  • Loading branch information
monojenkins and fanyang-mono authored Jan 31, 2020
1 parent 9db6eea commit e5c1f66
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 6 deletions.
16 changes: 10 additions & 6 deletions src/mono/mono/mini/branch-opts.c
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,16 @@ mono_if_conversion (MonoCompile *cfg)
MonoBasicBlock *bb1, *bb2;

restart:
if (!(bb->out_count == 2 && !bb->extended))
continue;

bb1 = bb->out_bb [0];
bb2 = bb->out_bb [1];

/* If either bb1 or bb2 is a try block, abort the optimization attempt. */
if (bb1->try_start || bb2->try_start)
continue;

/* Look for the IR code generated from cond ? a : b
* which is:
* BB:
Expand All @@ -315,12 +325,6 @@ mono_if_conversion (MonoCompile *cfg)
* <var> <- <b>
* br BB3
*/
if (!(bb->out_count == 2 && !bb->extended))
continue;

bb1 = bb->out_bb [0];
bb2 = bb->out_bb [1];

if (bb1->in_count == 1 && bb2->in_count == 1 && bb1->out_count == 1 && bb2->out_count == 1 && bb1->out_bb [0] == bb2->out_bb [0]) {
MonoInst *compare, *branch, *ins1, *ins2, *cmov, *move, *tmp;
MonoBasicBlock *true_bb, *false_bb;
Expand Down
66 changes: 66 additions & 0 deletions src/mono/mono/mini/iltests.il
Original file line number Diff line number Diff line change
Expand Up @@ -3491,4 +3491,70 @@ L3:
ret
}
*/

.method public hidebysig static string cmov_try_block_helper (string s) cil managed noinlining
{
// Code size 43 (0x2b)
.maxstack 2
.locals init (bool V_0, string V_1)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: callvirt instance int32 [mscorlib]System.String::get_Length()
IL_0007: ldc.i4.0
IL_0008: ceq
IL_000a: stloc.0
IL_000b: ldloc.0
IL_000c: brfalse.s IL_0016

IL_000e: ldstr "Empty"
IL_0013: stloc.1
IL_0014: br.s IL_0029

IL_0016: nop
.try
{
IL_0017: nop
IL_0018: ldarg.0
IL_0019: stloc.1
IL_001a: leave.s IL_0029
} // end .try
catch [mscorlib]System.Exception
{
IL_001c: pop
IL_001d: nop
IL_001e: nop
IL_001f: leave.s IL_0021
} // end handler
IL_0021: ldstr "Should not happen"
IL_0026: stloc.1
IL_0027: br.s IL_0029

IL_0029: ldloc.1
IL_002a: ret
}

.method public hidebysig static int32 test_1_cmov_try_block() cil managed
{
// Code size 37 (0x25)
.maxstack 2
.locals init (string V_0, bool V_1, int32 V_2)
IL_0000: nop
IL_0001: ldstr "abc"
IL_0006: call string Tests::cmov_try_block_helper(string)
IL_000d: ldstr "abc"
IL_0012: call bool [mscorlib]System.String::op_Equality(string,string)
IL_0019: brfalse.s IL_001f

IL_001b: ldc.i4.1
IL_001c: stloc.2
IL_001d: br.s IL_0023

IL_001f: ldc.i4.0
IL_0020: stloc.2
IL_0021: br.s IL_0023

IL_0023: ldloc.2
IL_0024: ret
}

}

0 comments on commit e5c1f66

Please sign in to comment.