diff --git a/cranelift/filetests/simple_gvn/reject.cton b/cranelift/filetests/simple_gvn/reject.cton index 1bb6ad16fa..5544ddbd75 100644 --- a/cranelift/filetests/simple_gvn/reject.cton +++ b/cranelift/filetests/simple_gvn/reject.cton @@ -23,3 +23,19 @@ ebb0: v5 = iadd v4, v3 return v5 } + +function %cpu_flags() -> b1 { +ebb0: + v0 = iconst.i32 7 + v1 = iconst.i32 8 + v2 = ifcmp v0, v1 + v3 = trueif eq v2 + v4 = ifcmp v0, v1 + v5 = trueif eq v4 + v6 = bor v3, v5 +; check: v2 = ifcmp v0, v1 +; check: v3 = trueif eq v2 +; check: v4 = ifcmp v0, v1 +; check: v5 = trueif eq v4 + return v6 +} diff --git a/lib/cretonne/meta/cdsl/instructions.py b/lib/cretonne/meta/cdsl/instructions.py index d295f59b41..8c66b400fb 100644 --- a/lib/cretonne/meta/cdsl/instructions.py +++ b/lib/cretonne/meta/cdsl/instructions.py @@ -110,6 +110,7 @@ class Instruction(object): 'can_trap': 'Can this instruction cause a trap?', 'other_side_effects': 'Does this instruction have other side effects besides can_*', + 'writes_cpu_flags': 'Does this instruction write to CPU flags?', } def __init__(self, name, doc, ins=(), outs=(), constraints=(), **kwargs): @@ -144,6 +145,10 @@ class Instruction(object): "unknown instruction attribute '" + attr + "'") for attr in Instruction.ATTRIBS: setattr(self, attr, not not kwargs.get(attr, False)) + + # Infer the 'writes_cpu_flags' field value. + setattr(self, 'writes_cpu_flags', any(out.is_cpu_flags() for out in self.outs)) + InstructionGroup.append(self) def __str__(self): diff --git a/lib/cretonne/meta/cdsl/operands.py b/lib/cretonne/meta/cdsl/operands.py index 85d4adef99..b6f81e4c26 100644 --- a/lib/cretonne/meta/cdsl/operands.py +++ b/lib/cretonne/meta/cdsl/operands.py @@ -242,3 +242,10 @@ class Operand(object): dependency. """ return self.kind is not VALUE and self.kind is not VARIABLE_ARGS + + def is_cpu_flags(self): + # type: () -> bool + """ + Is this a CPU flags operand? + """ + return self.kind is VALUE and self.typevar.name in ['iflags', 'fflags'] diff --git a/lib/cretonne/src/simple_gvn.rs b/lib/cretonne/src/simple_gvn.rs index b59f6bafd8..708a287904 100644 --- a/lib/cretonne/src/simple_gvn.rs +++ b/lib/cretonne/src/simple_gvn.rs @@ -10,7 +10,7 @@ use scoped_hash_map::ScopedHashMap; fn trivially_unsafe_for_gvn(opcode: Opcode) -> bool { opcode.is_call() || opcode.is_branch() || opcode.is_terminator() || opcode.is_return() || opcode.can_trap() || opcode.other_side_effects() || - opcode.can_store() || opcode.can_load() + opcode.can_store() || opcode.can_load() || opcode.writes_cpu_flags() } /// Perform simple GVN on `func`.