;;<< << << << << << << << << << << << << << << << << << << << << << << << << <<
;; arithmetic shift left
+;; Work around PR120423: Transform left shift of a paradoxical subreg
+;; into left shift of the zero-extended entity.
+(define_split ; PR120423
+ [(set (match_operand:HISI 0 "register_operand")
+ (ashift:HISI (subreg:HISI (match_operand:QIPSI 1 "nonimmediate_operand")
+ 0)
+ (match_operand:QI 2 "const_int_operand")))]
+ "!reload_completed
+ && !avropt_lra_p
+ && <HISI:SIZE> > <QIPSI:SIZE>"
+ [(set (match_dup 4)
+ (zero_extend:HISI (match_dup 5)))
+ (set (match_dup 0)
+ (ashift:HISI (match_dup 4)
+ (match_dup 2)))]
+ {
+ operands[4] = gen_reg_rtx (<HISI:MODE>mode);
+ operands[5] = force_reg (<QIPSI:MODE>mode, operands[1]);
+ })
+
+;; Similar happens for PR116389.
+(define_split ; PR116389
+ [(set (match_operand:HISI 0 "register_operand")
+ (subreg:HISI (match_operand:QIPSI 1 "nonimmediate_operand")
+ 0))]
+ "!reload_completed
+ && !avropt_lra_p
+ && <HISI:SIZE> > <QIPSI:SIZE>"
+ [(set (match_dup 0)
+ (zero_extend:HISI (match_dup 2)))]
+ {
+ operands[2] = force_reg (<QIPSI:MODE>mode, operands[1]);
+ })
+
+
;; "ashlqi3"
;; "ashlqq3" "ashluqq3"
(define_expand "ashl<mode>3"
--- /dev/null
+/* { dg-do compile } */
+
+struct data
+{
+ int a;
+ int b;
+ long c;
+};
+
+unsigned char val;
+unsigned val2;
+
+void func1 (struct data *d)
+{
+ d->a = 0;
+ d->b = 0x100 * val - 1;
+}
+
+void func2 (struct data *d)
+{
+ d->a = 0;
+ d->c = 0x10000 * val2 - 1;
+}
+
+void func3 (struct data *d)
+{
+ d->a = 0;
+ d->c = 0x1000000 * val - 1;
+}
--- /dev/null
+/* { dg-do compile } */
+/* { dg-additional-options "-ffixed-18 -ffixed-20 -ffixed-22" } */
+
+struct data
+{
+ int a;
+ int b;
+ long c;
+};
+
+unsigned char val;
+unsigned val2;
+
+void func1 (struct data *d)
+{
+ d->a = 0;
+ d->b = 0x100 * val - 1;
+}
+
+void func2 (struct data *d)
+{
+ d->a = 0;
+ d->c = 0x10000 * val2 - 1;
+}
+
+void func3 (struct data *d)
+{
+ d->a = 0;
+ d->c = 0x1000000 * val - 1;
+}