Skip to content

Commit

Permalink
x86: Fix redundant compare elimination
Browse files Browse the repository at this point in the history
Redundant compare elimination is a code
generation optimization that attempts to drop
redundant compare instructions before a jump.
This can happen when the the previous
instruction sets condition code flags and is
compared with 0. However, some instructions
such as DIV and IDIV can modify these flags
in undefined ways. This commit lets the code
the code generator know that these instructions
may modify condition code flags. In addition,
the code generator should check if the
instruction that modifies these flags belongs
to the expected node.

Fixes: eclipse-openj9/openj9#17496

Signed-off-by: Bradley Wood <bradley.wood@ibm.com>
  • Loading branch information
BradleyWood committed Jun 5, 2023
1 parent 283d187 commit 0478a92
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 12 deletions.
3 changes: 3 additions & 0 deletions compiler/x/codegen/ControlFlowEvaluator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,9 @@ bool isConditionCodeSetForCompareToZero(TR::Node *node, bool justTestZeroFlag)
return false;
}

if (prevInstr->getOpCode().modifiesSomeArithmeticFlags() && prevInstr->getNode() != node)
return false;

return true;
}
}
Expand Down
24 changes: 12 additions & 12 deletions compiler/x/codegen/X86Ops.ins
Original file line number Diff line number Diff line change
Expand Up @@ -1884,62 +1884,62 @@ INSTRUCTION(FXCHReg, fxch,
FEATURES(0)),
INSTRUCTION(IDIV1AccReg, idiv,
BINARY(VEX_L___, VEX_vNONE, PREFIX___, REX__, ESCAPE_____, 0xf6, 7, ModRM_EXT_, Immediate_0),
PROPERTY0(IA32OpProp_ModifiesTarget | IA32OpProp_SourceRegisterInModRM | IA32OpProp_TargetRegisterIgnored | IA32OpProp_ByteSource | IA32OpProp_ByteTarget | IA32OpProp_UsesTarget),
PROPERTY0(IA32OpProp_ModifiesTarget | IA32OpProp_SourceRegisterInModRM | IA32OpProp_TargetRegisterIgnored | IA32OpProp_ByteSource | IA32OpProp_ByteTarget | IA32OpProp_UsesTarget | IA32OpProp_ModifiesOverflowFlag | IA32OpProp_ModifiesSignFlag | IA32OpProp_ModifiesZeroFlag | IA32OpProp_ModifiesParityFlag | IA32OpProp_ModifiesCarryFlag),
PROPERTY1(IA32OpProp1_TargetRegIsImplicit),
FEATURES(0)),
INSTRUCTION(IDIV2AccReg, idiv,
BINARY(VEX_L___, VEX_vNONE, PREFIX_66, REX__, ESCAPE_____, 0xf7, 7, ModRM_EXT_, Immediate_0),
PROPERTY0(IA32OpProp_ModifiesTarget | IA32OpProp_SourceRegisterInModRM | IA32OpProp_TargetRegisterIgnored | IA32OpProp_ShortSource | IA32OpProp_ShortTarget | IA32OpProp_UsesTarget),
PROPERTY0(IA32OpProp_ModifiesTarget | IA32OpProp_SourceRegisterInModRM | IA32OpProp_TargetRegisterIgnored | IA32OpProp_ShortSource | IA32OpProp_ShortTarget | IA32OpProp_UsesTarget | IA32OpProp_ModifiesOverflowFlag | IA32OpProp_ModifiesSignFlag | IA32OpProp_ModifiesZeroFlag | IA32OpProp_ModifiesParityFlag | IA32OpProp_ModifiesCarryFlag),
PROPERTY1(IA32OpProp1_TargetRegIsImplicit),
FEATURES(0)),
INSTRUCTION(IDIV4AccReg, idiv,
BINARY(VEX_L___, VEX_vNONE, PREFIX___, REX__, ESCAPE_____, 0xf7, 7, ModRM_EXT_, Immediate_0),
PROPERTY0(IA32OpProp_ModifiesTarget | IA32OpProp_SourceRegisterInModRM | IA32OpProp_TargetRegisterIgnored | IA32OpProp_IntSource | IA32OpProp_IntTarget | IA32OpProp_UsesTarget),
PROPERTY0(IA32OpProp_ModifiesTarget | IA32OpProp_SourceRegisterInModRM | IA32OpProp_TargetRegisterIgnored | IA32OpProp_IntSource | IA32OpProp_IntTarget | IA32OpProp_UsesTarget | IA32OpProp_ModifiesOverflowFlag | IA32OpProp_ModifiesSignFlag | IA32OpProp_ModifiesZeroFlag | IA32OpProp_ModifiesParityFlag | IA32OpProp_ModifiesCarryFlag),
PROPERTY1(IA32OpProp1_TargetRegIsImplicit),
FEATURES(0)),
INSTRUCTION(IDIV8AccReg, idiv,
BINARY(VEX_L___, VEX_vNONE, PREFIX___, REX_W, ESCAPE_____, 0xf7, 7, ModRM_EXT_, Immediate_0),
PROPERTY0(IA32OpProp_ModifiesTarget | IA32OpProp_SourceRegisterInModRM | IA32OpProp_TargetRegisterIgnored | IA32OpProp_UsesTarget),
PROPERTY0(IA32OpProp_ModifiesTarget | IA32OpProp_SourceRegisterInModRM | IA32OpProp_TargetRegisterIgnored | IA32OpProp_UsesTarget | IA32OpProp_ModifiesOverflowFlag | IA32OpProp_ModifiesSignFlag | IA32OpProp_ModifiesZeroFlag | IA32OpProp_ModifiesParityFlag | IA32OpProp_ModifiesCarryFlag),
PROPERTY1(IA32OpProp1_LongSource | IA32OpProp1_LongTarget | IA32OpProp1_TargetRegIsImplicit),
FEATURES(0)),
INSTRUCTION(DIV4AccReg, div,
BINARY(VEX_L___, VEX_vNONE, PREFIX___, REX__, ESCAPE_____, 0xf7, 6, ModRM_EXT_, Immediate_0),
PROPERTY0(IA32OpProp_ModifiesTarget | IA32OpProp_SourceRegisterInModRM | IA32OpProp_TargetRegisterIgnored | IA32OpProp_IntSource | IA32OpProp_IntTarget | IA32OpProp_UsesTarget),
PROPERTY0(IA32OpProp_ModifiesTarget | IA32OpProp_SourceRegisterInModRM | IA32OpProp_TargetRegisterIgnored | IA32OpProp_IntSource | IA32OpProp_IntTarget | IA32OpProp_UsesTarget | IA32OpProp_ModifiesOverflowFlag | IA32OpProp_ModifiesSignFlag | IA32OpProp_ModifiesZeroFlag | IA32OpProp_ModifiesParityFlag | IA32OpProp_ModifiesCarryFlag),
PROPERTY1(0),
FEATURES(0)),
INSTRUCTION(DIV8AccReg, div,
BINARY(VEX_L___, VEX_vNONE, PREFIX___, REX_W, ESCAPE_____, 0xf7, 6, ModRM_EXT_, Immediate_0),
PROPERTY0(IA32OpProp_ModifiesTarget | IA32OpProp_SourceRegisterInModRM | IA32OpProp_TargetRegisterIgnored | IA32OpProp_UsesTarget),
PROPERTY0(IA32OpProp_ModifiesTarget | IA32OpProp_SourceRegisterInModRM | IA32OpProp_TargetRegisterIgnored | IA32OpProp_UsesTarget | IA32OpProp_ModifiesOverflowFlag | IA32OpProp_ModifiesSignFlag | IA32OpProp_ModifiesZeroFlag | IA32OpProp_ModifiesParityFlag | IA32OpProp_ModifiesCarryFlag),
PROPERTY1(IA32OpProp1_LongSource | IA32OpProp1_LongTarget),
FEATURES(0)),
INSTRUCTION(IDIV1AccMem, idiv,
BINARY(VEX_L___, VEX_vNONE, PREFIX___, REX__, ESCAPE_____, 0xf6, 7, ModRM_EXT_, Immediate_0),
PROPERTY0(IA32OpProp_ModifiesTarget | IA32OpProp_TargetRegisterIgnored | IA32OpProp_ByteSource | IA32OpProp_ByteTarget | IA32OpProp_UsesTarget),
PROPERTY0(IA32OpProp_ModifiesTarget | IA32OpProp_TargetRegisterIgnored | IA32OpProp_ByteSource | IA32OpProp_ByteTarget | IA32OpProp_UsesTarget | IA32OpProp_ModifiesOverflowFlag | IA32OpProp_ModifiesSignFlag | IA32OpProp_ModifiesZeroFlag | IA32OpProp_ModifiesParityFlag | IA32OpProp_ModifiesCarryFlag),
PROPERTY1(IA32OpProp1_SourceIsMemRef | IA32OpProp1_TargetRegIsImplicit),
FEATURES(0)),
INSTRUCTION(IDIV2AccMem, idiv,
BINARY(VEX_L___, VEX_vNONE, PREFIX_66, REX__, ESCAPE_____, 0xf7, 7, ModRM_EXT_, Immediate_0),
PROPERTY0(IA32OpProp_ModifiesTarget | IA32OpProp_TargetRegisterIgnored | IA32OpProp_ShortSource | IA32OpProp_ShortTarget | IA32OpProp_UsesTarget),
PROPERTY0(IA32OpProp_ModifiesTarget | IA32OpProp_TargetRegisterIgnored | IA32OpProp_ShortSource | IA32OpProp_ShortTarget | IA32OpProp_UsesTarget | IA32OpProp_ModifiesOverflowFlag | IA32OpProp_ModifiesSignFlag | IA32OpProp_ModifiesZeroFlag | IA32OpProp_ModifiesParityFlag | IA32OpProp_ModifiesCarryFlag),
PROPERTY1(IA32OpProp1_SourceIsMemRef | IA32OpProp1_TargetRegIsImplicit),
FEATURES(0)),
INSTRUCTION(IDIV4AccMem, idiv,
BINARY(VEX_L___, VEX_vNONE, PREFIX___, REX__, ESCAPE_____, 0xf7, 7, ModRM_EXT_, Immediate_0),
PROPERTY0(IA32OpProp_ModifiesTarget | IA32OpProp_TargetRegisterIgnored | IA32OpProp_IntSource | IA32OpProp_IntTarget | IA32OpProp_UsesTarget),
PROPERTY0(IA32OpProp_ModifiesTarget | IA32OpProp_TargetRegisterIgnored | IA32OpProp_IntSource | IA32OpProp_IntTarget | IA32OpProp_UsesTarget | IA32OpProp_ModifiesOverflowFlag | IA32OpProp_ModifiesSignFlag | IA32OpProp_ModifiesZeroFlag | IA32OpProp_ModifiesParityFlag | IA32OpProp_ModifiesCarryFlag),
PROPERTY1(IA32OpProp1_SourceIsMemRef | IA32OpProp1_TargetRegIsImplicit),
FEATURES(0)),
INSTRUCTION(IDIV8AccMem, idiv,
BINARY(VEX_L___, VEX_vNONE, PREFIX___, REX_W, ESCAPE_____, 0xf7, 7, ModRM_EXT_, Immediate_0),
PROPERTY0(IA32OpProp_ModifiesTarget | IA32OpProp_TargetRegisterIgnored | IA32OpProp_UsesTarget),
PROPERTY0(IA32OpProp_ModifiesTarget | IA32OpProp_TargetRegisterIgnored | IA32OpProp_UsesTarget | IA32OpProp_ModifiesOverflowFlag | IA32OpProp_ModifiesSignFlag | IA32OpProp_ModifiesZeroFlag | IA32OpProp_ModifiesParityFlag | IA32OpProp_ModifiesCarryFlag),
PROPERTY1(IA32OpProp1_LongSource | IA32OpProp1_LongTarget | IA32OpProp1_SourceIsMemRef | IA32OpProp1_TargetRegIsImplicit),
FEATURES(0)),
INSTRUCTION(DIV4AccMem, div,
BINARY(VEX_L___, VEX_vNONE, PREFIX___, REX__, ESCAPE_____, 0xf7, 6, ModRM_EXT_, Immediate_0),
PROPERTY0(IA32OpProp_ModifiesTarget | IA32OpProp_TargetRegisterIgnored | IA32OpProp_IntSource | IA32OpProp_IntTarget | IA32OpProp_UsesTarget),
PROPERTY0(IA32OpProp_ModifiesTarget | IA32OpProp_TargetRegisterIgnored | IA32OpProp_IntSource | IA32OpProp_IntTarget | IA32OpProp_UsesTarget | IA32OpProp_ModifiesOverflowFlag | IA32OpProp_ModifiesSignFlag | IA32OpProp_ModifiesZeroFlag | IA32OpProp_ModifiesParityFlag | IA32OpProp_ModifiesCarryFlag),
PROPERTY1(IA32OpProp1_SourceIsMemRef),
FEATURES(0)),
INSTRUCTION(DIV8AccMem, div,
BINARY(VEX_L___, VEX_vNONE, PREFIX___, REX_W, ESCAPE_____, 0xf7, 6, ModRM_EXT_, Immediate_0),
PROPERTY0(IA32OpProp_ModifiesTarget | IA32OpProp_TargetRegisterIgnored | IA32OpProp_UsesTarget),
PROPERTY0(IA32OpProp_ModifiesTarget | IA32OpProp_TargetRegisterIgnored | IA32OpProp_UsesTarget | IA32OpProp_ModifiesOverflowFlag | IA32OpProp_ModifiesSignFlag | IA32OpProp_ModifiesZeroFlag | IA32OpProp_ModifiesParityFlag | IA32OpProp_ModifiesCarryFlag),
PROPERTY1(IA32OpProp1_LongSource | IA32OpProp1_LongTarget | IA32OpProp1_SourceIsMemRef),
FEATURES(0)),
INSTRUCTION(DIVSSRegReg, divss,
Expand Down

0 comments on commit 0478a92

Please sign in to comment.