diff --git a/cranelift/filetests/isa/riscv/expand-i32.cton b/cranelift/filetests/isa/riscv/expand-i32.cton new file mode 100644 index 0000000000..b2473aa608 --- /dev/null +++ b/cranelift/filetests/isa/riscv/expand-i32.cton @@ -0,0 +1,18 @@ +; Test the legalization of i32 instructions that don't have RISC-V versions. +test legalizer + +set is_64bit=0 +isa riscv supports_m=1 + +set is_64bit=1 +isa riscv supports_m=1 + +; regex: V=vx?\d+ + +function carry_out(i32, i32) -> i32, b1 { +ebb0(v1: i32, v2: i32): + v3, v4 = iadd_cout v1, v2 + return v3, v4 +} +; check: $v3 = iadd $v1, $v2 +; check: $(cout=$V) = icmp ult, $v3, $v1 diff --git a/lib/cretonne/meta/gen_legalizer.py b/lib/cretonne/meta/gen_legalizer.py index 3efb120124..bc662dca8b 100644 --- a/lib/cretonne/meta/gen_legalizer.py +++ b/lib/cretonne/meta/gen_legalizer.py @@ -105,6 +105,7 @@ def wrap_tup(seq): def emit_dst_inst(node, fmt): # type: (Def, Formatter) -> None exact_replace = False + replaced_inst = None # type: str if len(node.defs) == 0: # This node doesn't define any values, so just insert the new # instruction. @@ -116,6 +117,7 @@ def emit_dst_inst(node, fmt): # pattern. # Replace the whole instruction. builder = 'let {} = dfg.replace(inst)'.format(wrap_tup(node.defs)) + replaced_inst = 'inst' # Secondary values weren't replaced if this is an exact replacement # for all the src results. exact_replace = (node.defs == src_def0.defs) @@ -126,6 +128,14 @@ def emit_dst_inst(node, fmt): fmt.line('{}.{};'.format(builder, node.expr.rust_builder())) + # If we just replaced an instruction, we need to bump the cursor so + # following instructions are inserted *after* the replaced insruction. + if replaced_inst: + with fmt.indented( + 'if pos.current_inst() == Some({}) {{' + .format(replaced_inst), '}'): + fmt.line('pos.next_inst();') + if exact_replace: fmt.comment('exactreplacement') @@ -151,12 +161,7 @@ def gen_xform(xform, fmt): def gen_xform_group(xgrp, fmt): # type: (XFormGroup, Formatter) -> None - fmt.doc_comment(""" - Legalize the instruction pointed to by `pos`. - - Return the first instruction in the expansion, and leave `pos` pointing - at the last instruction in the expansion. - """) + fmt.doc_comment("Legalize the instruction pointed to by `pos`.") fmt.line('#[allow(unused_variables,unused_assignments)]') with fmt.indented( 'fn ' + xgrp.name +