Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFan Yang <52458914+fanyang-mono@users.noreply.github.com>2020-02-01 00:40:47 +0300
committerGitHub <noreply@github.com>2020-02-01 00:40:47 +0300
commit3a93ebd6fee0a42c4dece98f0baca9b7008cbfc6 (patch)
treeebf9024b6ac96406126b14df0e8103b717bb8b9e
parent9ea6b6a58a022ee022b4c3b06edbbee8e346d56d (diff)
Abort cmov optimization, when one of the out blocks is try block (#18626)
-rw-r--r--mono/mini/branch-opts.c16
-rw-r--r--mono/mini/iltests.il66
2 files changed, 76 insertions, 6 deletions
diff --git a/mono/mini/branch-opts.c b/mono/mini/branch-opts.c
index 15c2a76d674..67eabd7c082 100644
--- a/mono/mini/branch-opts.c
+++ b/mono/mini/branch-opts.c
@@ -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:
@@ -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;
diff --git a/mono/mini/iltests.il b/mono/mini/iltests.il
index 40c55e63e9b..ba6aba836d4 100644
--- a/mono/mini/iltests.il
+++ b/mono/mini/iltests.il
@@ -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
+ }
+
}