[llvm] [InstCombine] enable more factorization in SimplifyUsingDistributiveLaws (PR #69892)

via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 24 11:04:20 PDT 2023


================
@@ -127,3 +129,184 @@ define i32 @not_match_overflow(i32 %x) {
   %t4 = add i32 %t, %t3
   ret i32 %t4
 }
+
+; (x + (-1)) + (x * 5) --> (x * 6) + (-1)
+define i8 @mul_add_common_factor_0(i8 %x) {
+; CHECK-LABEL: @mul_add_common_factor_0(
+; CHECK-NEXT:    [[A1:%.*]] = mul i8 [[X:%.*]], 6
+; CHECK-NEXT:    [[TMP1:%.*]] = add i8 [[A1]], -1
+; CHECK-NEXT:    ret i8 [[TMP1]]
+;
+  %a0 = add i8 %x, -1
+  %m = mul i8 %x, 5
+  %a1 = add i8 %a0, %m ; the mul operand is the right operand, should swap the operand
+  ret i8 %a1
+}
+
+; (x * 4) + (x - 1) --> (x * 5) + (-1)
+define i16 @mul_add_common_factor_1(i16 %x) {
+; CHECK-LABEL: @mul_add_common_factor_1(
+; CHECK-NEXT:    [[A1:%.*]] = mul i16 [[X:%.*]], 5
+; CHECK-NEXT:    [[TMP1:%.*]] = add i16 [[A1]], -1
+; CHECK-NEXT:    ret i16 [[TMP1]]
+;
+  %a0 = add i16 %x, -1
+  %m = mul i16 %x, 4
+  %a1 = add i16 %m, %a0 ; the mul operand is the left operand
+  ret i16 %a1
+}
+
+; Negative test: y is not a const for (x + y) + (x * 4) --> (x * 5) + y
+define i32 @mul_add_common_factor_2(i32 %x, i32 %y) {
+; CHECK-LABEL: @mul_add_common_factor_2(
+; CHECK-NEXT:    [[A0:%.*]] = add i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[M:%.*]] = shl i32 [[X]], 2
+; CHECK-NEXT:    [[A1:%.*]] = add i32 [[A0]], [[M]]
+; CHECK-NEXT:    ret i32 [[A1]]
+;
+  %a0 = add i32 %x, %y
+  %m = mul i32 %x, 4
+  %a1 = add i32 %a0, %m
+  ret i32 %a1
+}
+
+; Negative test: y is not a const for (y + x) + (x * 4) --> (x * 5) + y
+define i32 @mul_add_common_factor_2_commute(i32 %x, i32 %y) {
+; CHECK-LABEL: @mul_add_common_factor_2_commute(
+; CHECK-NEXT:    [[A0:%.*]] = add i32 [[Y:%.*]], [[X:%.*]]
+; CHECK-NEXT:    [[M:%.*]] = shl i32 [[X]], 2
+; CHECK-NEXT:    [[A1:%.*]] = add i32 [[A0]], [[M]]
+; CHECK-NEXT:    ret i32 [[A1]]
+;
+  %a0 = add i32 %y, %x
+  %m = mul i32 %x, 4
+  %a1 = add i32 %a0, %m
+  ret i32 %a1
+}
+
+; Negative test: t is not a const for (x + 2) + (x * t) --> (t + 1) * x + 2
+define i128 @mul_add_common_factor_3(i128 %x, i128 %t) {
+; CHECK-LABEL: @mul_add_common_factor_3(
+; CHECK-NEXT:    [[A0:%.*]] = add i128 [[X:%.*]], 2
+; CHECK-NEXT:    [[M:%.*]] = mul i128 [[X]], [[T:%.*]]
+; CHECK-NEXT:    [[A1:%.*]] = add i128 [[A0]], [[M]]
+; CHECK-NEXT:    ret i128 [[A1]]
+;
+  %a0 = add i128 %x, 2
+  %m = mul i128 %x, %t
+  %a1 = add i128 %a0, %m
+  ret i128 %a1
+}
+
+; Negative test: t is not a const for (x + 2) + (t * x) --> (t + 1) * x + 2
+define i128 @mul_add_common_factor_3_commute(i128 %x, i128 %t) {
+; CHECK-LABEL: @mul_add_common_factor_3_commute(
+; CHECK-NEXT:    [[A0:%.*]] = add i128 [[X:%.*]], 2
+; CHECK-NEXT:    [[M:%.*]] = mul i128 [[T:%.*]], [[X]]
+; CHECK-NEXT:    [[A1:%.*]] = add i128 [[A0]], [[M]]
+; CHECK-NEXT:    ret i128 [[A1]]
+;
+  %a0 = add i128 %x, 2
+  %m = mul i128 %t, %x
+  %a1 = add i128 %a0, %m
+  ret i128 %a1
+}
+
+; Negative test: The transformation should not create more instructions
+define i32 @mul_add_common_factor_4(i32 %x) {
+; CHECK-LABEL: @mul_add_common_factor_4(
+; CHECK-NEXT:    [[A0:%.*]] = add i32 [[X:%.*]], -1
+; CHECK-NEXT:    [[M:%.*]] = shl i32 [[X]], 2
+; CHECK-NEXT:    call void @use32(i32 [[A0]])
+; CHECK-NEXT:    [[A1:%.*]] = add i32 [[M]], [[A0]]
+; CHECK-NEXT:    ret i32 [[A1]]
+;
+  %a0 = add i32 %x, -1
+  %m = mul i32 %x, 4
+  call void @use32(i32 %a0) ; an extra use
+  %a1 = add i32 %m, %a0
+  ret i32 %a1
+}
+
+; (x * 4) + (x + 3) --> (x * 5) + 3
+define <2 x i8> @mul_add_common_factor_5(<2 x i8> %x) {
+; CHECK-LABEL: @mul_add_common_factor_5(
+; CHECK-NEXT:    [[A1:%.*]] = mul <2 x i8> [[X:%.*]], <i8 5, i8 5>
+; CHECK-NEXT:    [[TMP1:%.*]] = add <2 x i8> [[A1]], <i8 3, i8 3>
+; CHECK-NEXT:    ret <2 x i8> [[TMP1]]
+;
+  %a0 = add <2 x i8> %x, <i8 3, i8 3>
+  %m = mul <2 x i8> %x, <i8 4, i8 4> ; vector type
+  %a1 = add <2 x i8> %m, %a0
+  ret <2 x i8> %a1
+}
+
+; (x << 2) + (x - 1) --> (x * 5) + (-1)
+define i16 @shl_add_common_factor_1(i16 %x) {
+; CHECK-LABEL: @shl_add_common_factor_1(
+; CHECK-NEXT:    [[A1:%.*]] = mul i16 [[X:%.*]], 5
+; CHECK-NEXT:    [[TMP1:%.*]] = add i16 [[A1]], -1
+; CHECK-NEXT:    ret i16 [[TMP1]]
+;
+  %a0 = add i16 %x, -1
+  %s = shl i16 %x, 2
+  %a1 = add i16 %s, %a0 ; the shl operand is the left operand
+  ret i16 %a1
+}
+
+; Negative test: y is not a const for (y + x) + (x << 2)
+define i32 @shl_add_common_factor_2(i32 %x, i32 %y) {
+; CHECK-LABEL: @shl_add_common_factor_2(
+; CHECK-NEXT:    [[A0:%.*]] = add i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[S:%.*]] = shl i32 [[X]], 2
+; CHECK-NEXT:    [[A1:%.*]] = add i32 [[A0]], [[S]]
+; CHECK-NEXT:    ret i32 [[A1]]
+;
+  %a0 = add i32 %x, %y
+  %s = shl i32 %x, 2
+  %a1 = add i32 %a0, %s ; the shl operand is the right operand
+  ret i32 %a1
+}
+
+; Negative test: y is not a const for (y + x) + (x << 2)
----------------
hiraditya wrote:

nit: this comment is a copy of previous?

https://github.com/llvm/llvm-project/pull/69892


More information about the llvm-commits mailing list