@@ -9093,7 +9093,6 @@ expand_expr_real_2 (sepops ops, rtx target, machine_mode tmode,
if (code == LSHIFT_EXPR
&& target
&& REG_P (target)
- && ! unsignedp
&& mode == GET_MODE_WIDER_MODE (word_mode)
&& GET_MODE_SIZE (mode) == 2 * GET_MODE_SIZE (word_mode)
&& TREE_CONSTANT (treeop1)
@@ -9114,6 +9113,8 @@ expand_expr_real_2 (sepops ops, rtx target, machine_mode tmode,
rtx_insn *seq, *seq_old;
unsigned int high_off = subreg_highpart_offset (word_mode,
mode);
+ bool extend_unsigned
+ = TYPE_UNSIGNED (TREE_TYPE (gimple_assign_rhs1 (def)));
rtx low = lowpart_subreg (word_mode, op0, mode);
rtx dest_low = lowpart_subreg (word_mode, target, mode);
rtx dest_high = simplify_gen_subreg (word_mode, target,
@@ -9125,7 +9126,8 @@ expand_expr_real_2 (sepops ops, rtx target, machine_mode tmode,
start_sequence ();
/* dest_high = src_low >> (word_size - C). */
temp = expand_variable_shift (RSHIFT_EXPR, word_mode, low,
- rshift, dest_high, unsignedp);
+ rshift, dest_high,
+ extend_unsigned);
if (temp != dest_high)
emit_move_insn (dest_high, temp);
new file mode 100644
@@ -0,0 +1,34 @@
+extern void abort (void);
+
+__attribute__ ((noinline, noclone)) unsigned long long f1 (int x)
+{
+ return ((unsigned long long) x) << 4;
+}
+
+__attribute__ ((noinline, noclone)) long long f2 (unsigned x)
+{
+ return ((long long) x) << 4;
+}
+
+__attribute__ ((noinline, noclone)) unsigned long long f3 (unsigned x)
+{
+ return ((unsigned long long) x) << 4;
+}
+
+__attribute__ ((noinline, noclone)) long long f4 (int x)
+{
+ return ((long long) x) << 4;
+}
+
+int main ()
+{
+ if (f1 (0xf0000000) != 0xffffffff00000000)
+ abort ();
+ if (f2 (0xf0000000) != 0xf00000000)
+ abort ();
+ if (f3 (0xf0000000) != 0xf00000000)
+ abort ();
+ if (f4 (0xf0000000) != 0xffffffff00000000)
+ abort ();
+ return 0;
+}