@@ -694,40 +694,115 @@ if.end: ; preds = %if.then, %lor.lhs.f
694694 ret i32 undef
695695}
696696
697+ ; ((X >> C) - Y) + Z --> (Z - Y) + (X >> C)
697698define i32 @commute_subop0 (i32 %x , i32 %y , i32 %z ) {
698699; CHECK-LABEL: commute_subop0:
699700; CHECK: // %bb.0:
700- ; CHECK-NEXT: lsl w8, w0, #3
701- ; CHECK-NEXT: sub w8, w8, w1
702- ; CHECK-NEXT: add w0, w8, w2
701+ ; CHECK-NEXT: sub w8, w2, w1
702+ ; CHECK-NEXT: add w0, w8, w0, lsl #3
703703; CHECK-NEXT: ret
704704 %shl = shl i32 %x , 3
705705 %sub = sub i32 %shl , %y
706706 %add = add i32 %sub , %z
707707 ret i32 %add
708708}
709709
710+ ; ((X << C) - Y) + Z --> (Z - Y) + (X << C)
711+ define i32 @commute_subop0_lshr (i32 %x , i32 %y , i32 %z ) {
712+ ; CHECK-LABEL: commute_subop0_lshr:
713+ ; CHECK: // %bb.0:
714+ ; CHECK-NEXT: lsr w8, w0, #3
715+ ; CHECK-NEXT: sub w8, w8, w1
716+ ; CHECK-NEXT: add w0, w8, w2
717+ ; CHECK-NEXT: ret
718+ %lshr = lshr i32 %x , 3
719+ %sub = sub i32 %lshr , %y
720+ %add = add i32 %sub , %z
721+ ret i32 %add
722+ }
723+
724+ ; ((X << C) - Y) + Z --> (Z - Y) + (X << C)
725+ define i32 @commute_subop0_ashr (i32 %x , i32 %y , i32 %z ) {
726+ ; CHECK-LABEL: commute_subop0_ashr:
727+ ; CHECK: // %bb.0:
728+ ; CHECK-NEXT: asr w8, w0, #3
729+ ; CHECK-NEXT: sub w8, w8, w1
730+ ; CHECK-NEXT: add w0, w8, w2
731+ ; CHECK-NEXT: ret
732+ %ashr = ashr i32 %x , 3
733+ %sub = sub i32 %ashr , %y
734+ %add = add i32 %sub , %z
735+ ret i32 %add
736+ }
737+
738+ ; Z + ((X >> C) - Y) --> (Z - Y) + (X >> C)
710739define i32 @commute_subop0_cadd (i32 %x , i32 %y , i32 %z ) {
711740; CHECK-LABEL: commute_subop0_cadd:
712741; CHECK: // %bb.0:
713- ; CHECK-NEXT: lsl w8, w0, #3
714- ; CHECK-NEXT: sub w8, w8, w1
715- ; CHECK-NEXT: add w0, w2, w8
742+ ; CHECK-NEXT: sub w8, w2, w1
743+ ; CHECK-NEXT: add w0, w8, w0, lsl #3
716744; CHECK-NEXT: ret
717745 %shl = shl i32 %x , 3
718746 %sub = sub i32 %shl , %y
719747 %add = add i32 %z , %sub
720748 ret i32 %add
721749}
722750
751+ ; Y + ((X >> C) - X) --> (Y - X) + (X >> C)
723752define i32 @commute_subop0_mul (i32 %x , i32 %y ) {
724753; CHECK-LABEL: commute_subop0_mul:
725754; CHECK: // %bb.0:
726- ; CHECK-NEXT: lsl w8, w0, #3
727- ; CHECK-NEXT: sub w8, w8, w0
728- ; CHECK-NEXT: add w0, w8, w1
755+ ; CHECK-NEXT: sub w8, w1, w0
756+ ; CHECK-NEXT: add w0, w8, w0, lsl #3
729757; CHECK-NEXT: ret
730758 %mul = mul i32 %x , 7
731759 %add = add i32 %mul , %y
732760 ret i32 %add
733761}
762+
763+ ; negative case for ((X >> C) - Y) + Z --> (Z - Y) + (X >> C)
764+ ; Y can't be constant to avoid dead loop
765+ define i32 @commute_subop0_zconst (i32 %x , i32 %y ) {
766+ ; CHECK-LABEL: commute_subop0_zconst:
767+ ; CHECK: // %bb.0:
768+ ; CHECK-NEXT: lsl w8, w0, #3
769+ ; CHECK-NEXT: sub w8, w8, w1
770+ ; CHECK-NEXT: add w0, w8, #1
771+ ; CHECK-NEXT: ret
772+ %shl = shl i32 %x , 3
773+ %sub = sub i32 %shl , %y
774+ %add = add i32 %sub , 1
775+ ret i32 %add
776+ }
777+
778+ ; negative case for ((X >> C) - Y) + Z --> (Z - Y) + (X >> C)
779+ ; Y can't be shift C also to avoid dead loop
780+ define i32 @commute_subop0_zshiftc_oneuse (i32 %x , i32 %y , i32 %z ) {
781+ ; CHECK-LABEL: commute_subop0_zshiftc_oneuse:
782+ ; CHECK: // %bb.0:
783+ ; CHECK-NEXT: lsl w8, w0, #3
784+ ; CHECK-NEXT: sub w8, w8, w1
785+ ; CHECK-NEXT: add w0, w8, w2, lsl #2
786+ ; CHECK-NEXT: ret
787+ %xshl = shl i32 %x , 3
788+ %sub = sub i32 %xshl , %y
789+ %zshl = shl i32 %z , 2
790+ %add = add i32 %sub , %zshl
791+ ret i32 %add
792+ }
793+
794+ define i32 @commute_subop0_zshiftc (i32 %x , i32 %y , i32 %z ) {
795+ ; CHECK-LABEL: commute_subop0_zshiftc:
796+ ; CHECK: // %bb.0:
797+ ; CHECK-NEXT: lsl w8, w2, #2
798+ ; CHECK-NEXT: sub w9, w8, w1
799+ ; CHECK-NEXT: add w9, w9, w0, lsl #3
800+ ; CHECK-NEXT: eor w0, w8, w9
801+ ; CHECK-NEXT: ret
802+ %xshl = shl i32 %x , 3
803+ %sub = sub i32 %xshl , %y
804+ %zshl = shl i32 %z , 2
805+ %add = add i32 %sub , %zshl
806+ %r = xor i32 %zshl , %add
807+ ret i32 %r
808+ }
0 commit comments