{
if (!register_operand (dest, mode) && !reg_or_0_operand (src, mode))
{
- loongarch_emit_move (dest, force_reg (mode, src));
+ /* When loading fixed-point scalar data, if the size of the mode
+ is smaller than the size of `word_mode`, the immediate value
+ is first loaded into a register of type `word_mode`.
+ This facilitates the elimination of common self-expressions.
+ This reduces redundant immediate value loading instructions. */
+ rtx tmp;
+ if (GET_MODE_CLASS (mode) == MODE_INT
+ && GET_CODE (src) == CONST_INT
+ && GET_MODE_SIZE (mode) < UNITS_PER_WORD)
+ tmp = gen_lowpart (mode, force_reg (word_mode, src));
+ else
+ tmp = force_reg (mode, src);
+
+ loongarch_emit_move (dest, tmp);
return true;
}
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-mabi=lp64d -O2" } */
+/* { dg-final { scan-assembler-times "addi.w\t\\\$r\[0-9\]+,\\\$r\[0-9\]+,1\t" 1 } } */
+
+extern unsigned short d;
+int
+test (int a, unsigned short b)
+{
+ if (a > 0)
+ {
+ d = 1;
+ if (b > d)
+ return 10;
+ }
+
+ return 50;
+}