diff --git a/amaranth/back/rtlil.py b/amaranth/back/rtlil.py
index ec7b699a1..a6367bdde 100644
--- a/amaranth/back/rtlil.py
+++ b/amaranth/back/rtlil.py
@@ -744,6 +744,16 @@ def emit_assignments(case, cond):
         emit_assignments(proc, _nir.Net.from_const(1))
         assert pos == len(cell.assignments)
 
+    def shorten_operand(self, value, *, signed):
+        value = list(value)
+        if signed:
+            while len(value) > 1 and value[-1] == value[-2]:
+                value.pop()
+        else:
+            while len(value) > 0 and value[-1] == _nir.Net.from_const(0):
+                value.pop()
+        return _nir.Value(value)
+
     def emit_operator(self, cell_idx, cell):
         UNARY_OPERATORS = {
             "-":    "$neg",
@@ -782,17 +792,75 @@ def emit_operator(self, cell_idx, cell):
         if len(cell.inputs) == 1:
             cell_type = UNARY_OPERATORS[cell.operator]
             operand, = cell.inputs
+            signed = False
+            if cell.operator == "-":
+                # For arithmetic operands, we trim the extra sign or zero extension on the operands
+                # to make the output prettier, and to fix inference problems in some not very smart
+                # synthesis tools.
+                operand_u = self.shorten_operand(operand, signed=False)
+                operand_s = self.shorten_operand(operand, signed=True)
+                # The operator will work when lowered with either signedness.  Pick whichever
+                # is prettier.
+                if len(operand_s) < len(operand_u):
+                    signed = True
+                    operand = operand_s
+                else:
+                    signed = False
+                    operand = operand_u
             self.builder.cell(cell_type, ports={
                 "A": self.sigspec(operand),
                 "Y": self.cell_wires[cell_idx].name
             }, parameters={
-                "A_SIGNED": False,
+                "A_SIGNED": signed,
                 "A_WIDTH": len(operand),
                 "Y_WIDTH": cell.width,
             }, src_loc=cell.src_loc)
         elif len(cell.inputs) == 2:
             cell_type, a_signed, b_signed = BINARY_OPERATORS[cell.operator]
             operand_a, operand_b = cell.inputs
+            if cell.operator in ("+", "-", "*", "==", "!="):
+                # Arithmetic operators that will work with any signedness, but we have to choose
+                # a common one for both operands. Prefer signed in case of mixed signedness.
+                operand_a_u = self.shorten_operand(operand_a, signed=False)
+                operand_b_u = self.shorten_operand(operand_b, signed=False)
+                operand_a_s = self.shorten_operand(operand_a, signed=True)
+                operand_b_s = self.shorten_operand(operand_b, signed=True)
+                if operand_a.is_const:
+                    # In case of constant operand, choose whichever shortens the other one better.
+                    signed = len(operand_b_s) < len(operand_b_u)
+                elif operand_b.is_const:
+                    signed = len(operand_a_s) < len(operand_a_u)
+                elif (len(operand_a_s) < len(operand_a) and len(operand_a_u) == len(operand_a)):
+                    # Operand A can only be shortened by signed. Pick it.
+                    signed = True
+                elif (len(operand_b_s) < len(operand_b) and len(operand_b_u) == len(operand_b)):
+                    # Operand B can only be shortened by signed. Pick it.
+                    signed = True
+                else:
+                    # Otherwise, use unsigned shortening.
+                    signed = False
+                if signed:
+                    operand_a = operand_a_s
+                    operand_b = operand_b_s
+                else:
+                    operand_a = operand_a_u
+                    operand_b = operand_b_u
+                a_signed = b_signed = signed
+            if cell.operator[0] in "us":
+                # Signedness forced, just shorten.
+                operand_a = self.shorten_operand(operand_a, signed=a_signed)
+                operand_b = self.shorten_operand(operand_b, signed=b_signed)
+            if cell.operator == "<<":
+                # We can pick the signedness for left operand, but right is fixed.
+                operand_a_u = self.shorten_operand(operand_a, signed=False)
+                operand_a_s = self.shorten_operand(operand_a, signed=True)
+                if len(operand_a_s) < len(operand_a_u):
+                    a_signed = True
+                    operand_a = operand_a_s
+                else:
+                    a_signed = False
+                    operand_a = operand_a_u
+                operand_b = self.shorten_operand(operand_b, signed=b_signed)
             if cell.operator in ("u//", "s//", "u%", "s%"):
                 result = self.builder.wire(cell.width)
                 self.builder.cell(cell_type, ports={
diff --git a/amaranth/hdl/_nir.py b/amaranth/hdl/_nir.py
index 72803b951..828e858ea 100644
--- a/amaranth/hdl/_nir.py
+++ b/amaranth/hdl/_nir.py
@@ -161,6 +161,10 @@ def __repr__(self):
         else:
             return f"(cat {' '.join(chunks)})"
 
+    @property
+    def is_const(self):
+        return all(net.is_const for net in self)
+
     __str__ = __repr__
 
 
diff --git a/tests/test_back_rtlil.py b/tests/test_back_rtlil.py
index 47d7b4b22..480a3f227 100644
--- a/tests/test_back_rtlil.py
+++ b/tests/test_back_rtlil.py
@@ -123,16 +123,16 @@ def test_operator_unary(self):
             wire width 1 $8
             cell $neg $9
                 parameter \A_SIGNED 0
-                parameter \A_WIDTH 9
+                parameter \A_WIDTH 8
                 parameter \Y_WIDTH 9
-                connect \A { 1'0 \i8u [7:0] }
+                connect \A \i8u [7:0]
                 connect \Y $1
             end
             cell $neg $10
-                parameter \A_SIGNED 0
-                parameter \A_WIDTH 9
+                parameter \A_SIGNED 1
+                parameter \A_WIDTH 8
                 parameter \Y_WIDTH 9
-                connect \A { \i8s [7] \i8s [7:0] }
+                connect \A \i8s [7:0]
                 connect \Y $2
             end
             cell $not $11
@@ -229,61 +229,61 @@ def test_operator_addsub(self):
             cell $add $5
                 parameter \A_SIGNED 0
                 parameter \B_SIGNED 0
-                parameter \A_WIDTH 9
-                parameter \B_WIDTH 9
+                parameter \A_WIDTH 8
+                parameter \B_WIDTH 8
                 parameter \Y_WIDTH 9
-                connect \A { 1'0 \i8ua [7:0] }
-                connect \B { 1'0 \i8ub [7:0] }
+                connect \A \i8ua [7:0]
+                connect \B \i8ub [7:0]
                 connect \Y $1
             end
             cell $add $6
-                parameter \A_SIGNED 0
-                parameter \B_SIGNED 0
-                parameter \A_WIDTH 10
-                parameter \B_WIDTH 10
+                parameter \A_SIGNED 1
+                parameter \B_SIGNED 1
+                parameter \A_WIDTH 9
+                parameter \B_WIDTH 8
                 parameter \Y_WIDTH 10
-                connect \A { 2'00 \i8ua [7:0] }
-                connect \B { \i8sb [7] \i8sb [7] \i8sb [7:0] }
+                connect \A { 1'0 \i8ua [7:0] }
+                connect \B \i8sb [7:0]
                 connect \Y \o2
             end
             cell $add $7
-                parameter \A_SIGNED 0
-                parameter \B_SIGNED 0
-                parameter \A_WIDTH 9
-                parameter \B_WIDTH 9
+                parameter \A_SIGNED 1
+                parameter \B_SIGNED 1
+                parameter \A_WIDTH 8
+                parameter \B_WIDTH 8
                 parameter \Y_WIDTH 9
-                connect \A { \i8sa [7] \i8sa [7:0] }
-                connect \B { \i8sb [7] \i8sb [7:0] }
+                connect \A \i8sa [7:0]
+                connect \B \i8sb [7:0]
                 connect \Y $2
             end
             cell $sub $8
                 parameter \A_SIGNED 0
                 parameter \B_SIGNED 0
-                parameter \A_WIDTH 9
-                parameter \B_WIDTH 9
+                parameter \A_WIDTH 8
+                parameter \B_WIDTH 8
                 parameter \Y_WIDTH 9
-                connect \A { 1'0 \i8ua [7:0] }
-                connect \B { 1'0 \i8ub [7:0] }
+                connect \A \i8ua [7:0]
+                connect \B \i8ub [7:0]
                 connect \Y $3
             end
             cell $sub $9
-                parameter \A_SIGNED 0
-                parameter \B_SIGNED 0
-                parameter \A_WIDTH 10
-                parameter \B_WIDTH 10
+                parameter \A_SIGNED 1
+                parameter \B_SIGNED 1
+                parameter \A_WIDTH 9
+                parameter \B_WIDTH 8
                 parameter \Y_WIDTH 10
-                connect \A { 2'00 \i8ua [7:0] }
-                connect \B { \i8sb [7] \i8sb [7] \i8sb [7:0] }
+                connect \A { 1'0 \i8ua [7:0] }
+                connect \B \i8sb [7:0]
                 connect \Y \o5
             end
             cell $sub $10
-                parameter \A_SIGNED 0
-                parameter \B_SIGNED 0
-                parameter \A_WIDTH 9
-                parameter \B_WIDTH 9
+                parameter \A_SIGNED 1
+                parameter \B_SIGNED 1
+                parameter \A_WIDTH 8
+                parameter \B_WIDTH 8
                 parameter \Y_WIDTH 9
-                connect \A { \i8sa [7] \i8sa [7:0] }
-                connect \B { \i8sb [7] \i8sb [7:0] }
+                connect \A \i8sa [7:0]
+                connect \B \i8sb [7:0]
                 connect \Y $4
             end
             connect \o1 { 1'0 $1 [8:0] }
@@ -293,6 +293,82 @@ def test_operator_addsub(self):
         end
         """)
 
+    def test_operator_add_imm(self):
+        i8u = Signal(8)
+        i8s = Signal(signed(8))
+        o1 = Signal(10)
+        o2 = Signal(10)
+        o3 = Signal(10)
+        o4 = Signal(10)
+        m = Module()
+        m.d.comb += [
+            o1.eq(i8u + 3),
+            o2.eq(i8s + 3),
+            o3.eq(3 + i8u),
+            o4.eq(3 + i8s),
+        ]
+        self.assertRTLIL(m, [i8u, i8s, o1, o2, o3, o4], R"""
+        attribute \generator "Amaranth"
+        attribute \top 1
+        module \top
+            wire width 8 input 0 \i8u
+            wire width 8 input 1 signed \i8s
+            wire width 10 output 2 \o1
+            wire width 10 output 3 \o2
+            wire width 10 output 4 \o3
+            wire width 10 output 5 \o4
+            wire width 9 $1
+            wire width 9 $2
+            wire width 9 $3
+            wire width 9 $4
+            cell $add $5
+                parameter \A_SIGNED 0
+                parameter \B_SIGNED 0
+                parameter \A_WIDTH 8
+                parameter \B_WIDTH 2
+                parameter \Y_WIDTH 9
+                connect \A \i8u [7:0]
+                connect \B 2'11
+                connect \Y $1
+            end
+            cell $add $6
+                parameter \A_SIGNED 1
+                parameter \B_SIGNED 1
+                parameter \A_WIDTH 8
+                parameter \B_WIDTH 3
+                parameter \Y_WIDTH 9
+                connect \A \i8s [7:0]
+                connect \B 3'011
+                connect \Y $2
+            end
+            cell $add $7
+                parameter \A_SIGNED 0
+                parameter \B_SIGNED 0
+                parameter \A_WIDTH 2
+                parameter \B_WIDTH 8
+                parameter \Y_WIDTH 9
+                connect \A 2'11
+                connect \B \i8u [7:0]
+                connect \Y $3
+            end
+            cell $add $8
+                parameter \A_SIGNED 1
+                parameter \B_SIGNED 1
+                parameter \A_WIDTH 3
+                parameter \B_WIDTH 8
+                parameter \Y_WIDTH 9
+                connect \A 3'011
+                connect \B \i8s [7:0]
+                connect \Y $4
+            end
+            connect \o1 { 1'0 $1 [8:0] }
+            connect \o2 { $2 [8] $2 [8:0] }
+            connect \o3 { 1'0 $3 [8:0] }
+            connect \o4 { $4 [8] $4 [8:0] }
+        end
+        """)
+
+
     def test_operator_mul(self):
         i4ua = Signal(4)
         i4ub = Signal(4)
@@ -324,31 +400,31 @@ def test_operator_mul(self):
             cell $mul $4
                 parameter \A_SIGNED 0
                 parameter \B_SIGNED 0
-                parameter \A_WIDTH 8
-                parameter \B_WIDTH 8
+                parameter \A_WIDTH 4
+                parameter \B_WIDTH 4
                 parameter \Y_WIDTH 8
-                connect \A { 4'0000 \i4ua [3:0] }
-                connect \B { 4'0000 \i4ub [3:0] }
+                connect \A \i4ua [3:0]
+                connect \B \i4ub [3:0]
                 connect \Y $1
             end
             cell $mul $5
-                parameter \A_SIGNED 0
-                parameter \B_SIGNED 0
-                parameter \A_WIDTH 8
-                parameter \B_WIDTH 8
+                parameter \A_SIGNED 1
+                parameter \B_SIGNED 1
+                parameter \A_WIDTH 5
+                parameter \B_WIDTH 4
                 parameter \Y_WIDTH 8
-                connect \A { 4'0000 \i4ua [3:0] }
-                connect \B { \i4sb [3] \i4sb [3] \i4sb [3] \i4sb [3] \i4sb [3:0] }
+                connect \A { 1'0 \i4ua [3:0] }
+                connect \B \i4sb [3:0]
                 connect \Y $2
             end
             cell $mul $6
-                parameter \A_SIGNED 0
-                parameter \B_SIGNED 0
-                parameter \A_WIDTH 8
-                parameter \B_WIDTH 8
+                parameter \A_SIGNED 1
+                parameter \B_SIGNED 1
+                parameter \A_WIDTH 4
+                parameter \B_WIDTH 4
                 parameter \Y_WIDTH 8
-                connect \A { \i4sa [3] \i4sa [3] \i4sa [3] \i4sa [3] \i4sa [3:0] }
-                connect \B { \i4sb [3] \i4sb [3] \i4sb [3] \i4sb [3] \i4sb [3:0] }
+                connect \A \i4sa [3:0]
+                connect \B \i4sb [3:0]
                 connect \Y $3
             end
             connect \o1 { 1'0 $1 [7:0] }
@@ -438,18 +514,18 @@ def test_operator_divmod(self):
                 parameter \A_SIGNED 1
                 parameter \B_SIGNED 1
                 parameter \A_WIDTH 5
-                parameter \B_WIDTH 5
+                parameter \B_WIDTH 4
                 parameter \Y_WIDTH 5
                 connect \A { 1'0 \i4ua [3:0] }
-                connect \B { \i4sb [3] \i4sb [3:0] }
+                connect \B \i4sb [3:0]
                 connect \Y $14
             end
             wire width 1 $16
             cell $reduce_bool $17
                 parameter \A_SIGNED 0
-                parameter \A_WIDTH 5
+                parameter \A_WIDTH 4
                 parameter \Y_WIDTH 1
-                connect \A { \i4sb [3] \i4sb [3:0] }
+                connect \A \i4sb [3:0]
                 connect \Y $16
             end
             cell $mux $18
@@ -464,10 +540,10 @@ def test_operator_divmod(self):
             cell $divfloor $20
                 parameter \A_SIGNED 1
                 parameter \B_SIGNED 1
-                parameter \A_WIDTH 5
+                parameter \A_WIDTH 4
                 parameter \B_WIDTH 5
                 parameter \Y_WIDTH 5
-                connect \A { \i4sa [3] \i4sa [3:0] }
+                connect \A \i4sa [3:0]
                 connect \B { 1'0 \i4ub [3:0] }
                 connect \Y $19
             end
@@ -491,19 +567,19 @@ def test_operator_divmod(self):
             cell $divfloor $25
                 parameter \A_SIGNED 1
                 parameter \B_SIGNED 1
-                parameter \A_WIDTH 5
-                parameter \B_WIDTH 5
+                parameter \A_WIDTH 4
+                parameter \B_WIDTH 4
                 parameter \Y_WIDTH 5
-                connect \A { \i4sa [3] \i4sa [3:0] }
-                connect \B { \i4sb [3] \i4sb [3:0] }
+                connect \A \i4sa [3:0]
+                connect \B \i4sb [3:0]
                 connect \Y $24
             end
             wire width 1 $26
             cell $reduce_bool $27
                 parameter \A_SIGNED 0
-                parameter \A_WIDTH 5
+                parameter \A_WIDTH 4
                 parameter \Y_WIDTH 1
-                connect \A { \i4sb [3] \i4sb [3:0] }
+                connect \A \i4sb [3:0]
                 connect \Y $26
             end
             cell $mux $28
@@ -546,18 +622,18 @@ def test_operator_divmod(self):
                 parameter \A_SIGNED 1
                 parameter \B_SIGNED 1
                 parameter \A_WIDTH 5
-                parameter \B_WIDTH 5
+                parameter \B_WIDTH 4
                 parameter \Y_WIDTH 5
                 connect \A { 1'0 \i4ua [3:0] }
-                connect \B { \i4sb [3] \i4sb [3:0] }
+                connect \B \i4sb [3:0]
                 connect \Y $34
             end
             wire width 1 $36
             cell $reduce_bool $37
                 parameter \A_SIGNED 0
-                parameter \A_WIDTH 5
+                parameter \A_WIDTH 4
                 parameter \Y_WIDTH 1
-                connect \A { \i4sb [3] \i4sb [3:0] }
+                connect \A \i4sb [3:0]
                 connect \Y $36
             end
             cell $mux $38
@@ -572,10 +648,10 @@ def test_operator_divmod(self):
             cell $modfloor $40
                 parameter \A_SIGNED 1
                 parameter \B_SIGNED 1
-                parameter \A_WIDTH 5
+                parameter \A_WIDTH 4
                 parameter \B_WIDTH 5
                 parameter \Y_WIDTH 5
-                connect \A { \i4sa [3] \i4sa [3:0] }
+                connect \A \i4sa [3:0]
                 connect \B { 1'0 \i4ub [3:0] }
                 connect \Y $39
             end
@@ -666,20 +742,20 @@ def test_operator_shift(self):
             cell $shl $5
                 parameter \A_SIGNED 0
                 parameter \B_SIGNED 0
-                parameter \A_WIDTH 15
+                parameter \A_WIDTH 8
                 parameter \B_WIDTH 3
                 parameter \Y_WIDTH 15
-                connect \A { 7'0000000 \i8ua [7:0] }
+                connect \A \i8ua [7:0]
                 connect \B \i3 [2:0]
                 connect \Y $1
             end
             cell $shl $6
-                parameter \A_SIGNED 0
+                parameter \A_SIGNED 1
                 parameter \B_SIGNED 0
-                parameter \A_WIDTH 15
+                parameter \A_WIDTH 8
                 parameter \B_WIDTH 3
                 parameter \Y_WIDTH 15
-                connect \A { \i8sa [7] \i8sa [7] \i8sa [7] \i8sa [7] \i8sa [7] \i8sa [7] \i8sa [7] \i8sa [7:0] }
+                connect \A \i8sa [7:0]
                 connect \B \i3 [2:0]
                 connect \Y $2
             end
@@ -822,13 +898,13 @@ def test_operator_eq(self):
                     connect \Y $1
                 end
                 cell $eqop $5
-                    parameter \A_SIGNED 0
-                    parameter \B_SIGNED 0
+                    parameter \A_SIGNED 1
+                    parameter \B_SIGNED 1
                     parameter \A_WIDTH 9
-                    parameter \B_WIDTH 9
+                    parameter \B_WIDTH 8
                     parameter \Y_WIDTH 1
                     connect \A { 1'0 \i8ua [7:0] }
-                    connect \B { \i8sb [7] \i8sb [7:0] }
+                    connect \B \i8sb [7:0]
                     connect \Y $2
                 end
                 cell $eqop $6
@@ -895,10 +971,10 @@ def test_operator_cmp(self):
                     parameter \A_SIGNED 1
                     parameter \B_SIGNED 1
                     parameter \A_WIDTH 9
-                    parameter \B_WIDTH 9
+                    parameter \B_WIDTH 8
                     parameter \Y_WIDTH 1
                     connect \A { 1'0 \i8ua [7:0] }
-                    connect \B { \i8sb [7] \i8sb [7:0] }
+                    connect \B \i8sb [7:0]
                     connect \Y $2
                 end
                 cell $cmpop $6