[llvm] r373597 - [NFC][InstCombine] Some tests for sub-of-negatible pattern

Roman Lebedev via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 3 06:36:00 PDT 2019


Author: lebedevri
Date: Thu Oct  3 06:36:00 2019
New Revision: 373597

URL: http://llvm.org/viewvc/llvm-project?rev=373597&view=rev
Log:
[NFC][InstCombine] Some tests for sub-of-negatible pattern

As we have previously estabilished, `sub` is an outcast,
and should be considered non-canonical iff it can be converted to `add`.

It can be converted to `add` if it's second operand can be negated.
So far we mostly only do that for constants and negation itself,
but we should be more through.

Added:
    llvm/trunk/test/Transforms/InstCombine/sub-of-negatible.ll

Added: llvm/trunk/test/Transforms/InstCombine/sub-of-negatible.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/sub-of-negatible.ll?rev=373597&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/sub-of-negatible.ll (added)
+++ llvm/trunk/test/Transforms/InstCombine/sub-of-negatible.ll Thu Oct  3 06:36:00 2019
@@ -0,0 +1,292 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt %s -instcombine -S | FileCheck %s
+
+declare void @use8(i8)
+
+; Constant can be freely negated.
+define i8 @t0(i8 %x) {
+; CHECK-LABEL: @t0(
+; CHECK-NEXT:    [[T0:%.*]] = add i8 [[X:%.*]], 42
+; CHECK-NEXT:    ret i8 [[T0]]
+;
+  %t0 = sub i8 %x, -42
+  ret i8 %t0
+}
+
+; Negation can be negated for free
+define i8 @t1(i8 %x, i8 %y) {
+; CHECK-LABEL: @t1(
+; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Y:%.*]]
+; CHECK-NEXT:    call void @use8(i8 [[T0]])
+; CHECK-NEXT:    [[T1:%.*]] = add i8 [[X:%.*]], [[Y]]
+; CHECK-NEXT:    ret i8 [[T1]]
+;
+  %t0 = sub i8 0, %y
+  call void @use8(i8 %t0)
+  %t1 = sub i8 %x, %t0
+  ret i8 %t1
+}
+
+; Shift-left can be negated if all uses can be updated
+define i8 @t2(i8 %x, i8 %y) {
+; CHECK-LABEL: @t2(
+; CHECK-NEXT:    [[T0:%.*]] = shl i8 -42, [[Y:%.*]]
+; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X:%.*]], [[T0]]
+; CHECK-NEXT:    ret i8 [[T1]]
+;
+  %t0 = shl i8 -42, %y
+  %t1 = sub i8 %x, %t0
+  ret i8 %t1
+}
+define i8 @n2(i8 %x, i8 %y) {
+; CHECK-LABEL: @n2(
+; CHECK-NEXT:    [[T0:%.*]] = shl i8 -42, [[Y:%.*]]
+; CHECK-NEXT:    call void @use8(i8 [[T0]])
+; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X:%.*]], [[T0]]
+; CHECK-NEXT:    ret i8 [[T1]]
+;
+  %t0 = shl i8 -42, %y
+  call void @use8(i8 %t0)
+  %t1 = sub i8 %x, %t0
+  ret i8 %t1
+}
+define i8 @t3(i8 %x, i8 %y, i8 %z) {
+; CHECK-LABEL: @t3(
+; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Z:%.*]]
+; CHECK-NEXT:    call void @use8(i8 [[T0]])
+; CHECK-NEXT:    [[T1:%.*]] = shl i8 [[T0]], [[Y:%.*]]
+; CHECK-NEXT:    [[T2:%.*]] = sub i8 [[X:%.*]], [[T1]]
+; CHECK-NEXT:    ret i8 [[T2]]
+;
+  %t0 = sub i8 0, %z
+  call void @use8(i8 %t0)
+  %t1 = shl i8 %t0, %y
+  %t2 = sub i8 %x, %t1
+  ret i8 %t2
+}
+define i8 @n3(i8 %x, i8 %y, i8 %z) {
+; CHECK-LABEL: @n3(
+; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Z:%.*]]
+; CHECK-NEXT:    call void @use8(i8 [[T0]])
+; CHECK-NEXT:    [[T1:%.*]] = shl i8 [[T0]], [[Y:%.*]]
+; CHECK-NEXT:    call void @use8(i8 [[T1]])
+; CHECK-NEXT:    [[T2:%.*]] = sub i8 [[X:%.*]], [[T1]]
+; CHECK-NEXT:    ret i8 [[T2]]
+;
+  %t0 = sub i8 0, %z
+  call void @use8(i8 %t0)
+  %t1 = shl i8 %t0, %y
+  call void @use8(i8 %t1)
+  %t2 = sub i8 %x, %t1
+  ret i8 %t2
+}
+
+; Select can be negated if all it's operands can be negated and all the users of select can be updated
+define i8 @t4(i8 %x, i1 %y) {
+; CHECK-LABEL: @t4(
+; CHECK-NEXT:    [[T0:%.*]] = select i1 [[Y:%.*]], i8 -42, i8 44
+; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X:%.*]], [[T0]]
+; CHECK-NEXT:    ret i8 [[T1]]
+;
+  %t0 = select i1 %y, i8 -42, i8 44
+  %t1 = sub i8 %x, %t0
+  ret i8 %t1
+}
+define i8 @n4(i8 %x, i1 %y) {
+; CHECK-LABEL: @n4(
+; CHECK-NEXT:    [[T0:%.*]] = select i1 [[Y:%.*]], i8 -42, i8 44
+; CHECK-NEXT:    call void @use8(i8 [[T0]])
+; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X:%.*]], [[T0]]
+; CHECK-NEXT:    ret i8 [[T1]]
+;
+  %t0 = select i1 %y, i8 -42, i8 44
+  call void @use8(i8 %t0)
+  %t1 = sub i8 %x, %t0
+  ret i8 %t1
+}
+define i8 @n5(i8 %x, i1 %y, i8 %z) {
+; CHECK-LABEL: @n5(
+; CHECK-NEXT:    [[T0:%.*]] = select i1 [[Y:%.*]], i8 -42, i8 [[Z:%.*]]
+; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X:%.*]], [[T0]]
+; CHECK-NEXT:    ret i8 [[T1]]
+;
+  %t0 = select i1 %y, i8 -42, i8 %z
+  %t1 = sub i8 %x, %t0
+  ret i8 %t1
+}
+define i8 @t6(i8 %x, i1 %y, i8 %z) {
+; CHECK-LABEL: @t6(
+; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Z:%.*]]
+; CHECK-NEXT:    call void @use8(i8 [[T0]])
+; CHECK-NEXT:    [[T1:%.*]] = select i1 [[Y:%.*]], i8 -42, i8 [[T0]]
+; CHECK-NEXT:    [[T2:%.*]] = sub i8 [[X:%.*]], [[T1]]
+; CHECK-NEXT:    ret i8 [[T2]]
+;
+  %t0 = sub i8 0, %z
+  call void @use8(i8 %t0)
+  %t1 = select i1 %y, i8 -42, i8 %t0
+  %t2 = sub i8 %x, %t1
+  ret i8 %t2
+}
+define i8 @t7(i8 %x, i1 %y, i8 %z) {
+; CHECK-LABEL: @t7(
+; CHECK-NEXT:    [[T0:%.*]] = shl i8 1, [[Z:%.*]]
+; CHECK-NEXT:    [[T1:%.*]] = select i1 [[Y:%.*]], i8 0, i8 [[T0]]
+; CHECK-NEXT:    [[T2:%.*]] = sub i8 [[X:%.*]], [[T1]]
+; CHECK-NEXT:    ret i8 [[T2]]
+;
+  %t0 = shl i8 1, %z
+  %t1 = select i1 %y, i8 0, i8 %t0
+  %t2 = sub i8 %x, %t1
+  ret i8 %t2
+}
+define i8 @n8(i8 %x, i1 %y, i8 %z) {
+; CHECK-LABEL: @n8(
+; CHECK-NEXT:    [[T0:%.*]] = shl i8 1, [[Z:%.*]]
+; CHECK-NEXT:    call void @use8(i8 [[T0]])
+; CHECK-NEXT:    [[T1:%.*]] = select i1 [[Y:%.*]], i8 0, i8 [[T0]]
+; CHECK-NEXT:    [[T2:%.*]] = sub i8 [[X:%.*]], [[T1]]
+; CHECK-NEXT:    ret i8 [[T2]]
+;
+  %t0 = shl i8 1, %z
+  call void @use8(i8 %t0)
+  %t1 = select i1 %y, i8 0, i8 %t0
+  %t2 = sub i8 %x, %t1
+  ret i8 %t2
+}
+
+; Subtraction can be negated if the first operand can be negated
+; x - (y - z) -> x - y + z -> x + (-y) + z
+define i8 @t9(i8 %x, i8 %y, i8 %z) {
+; CHECK-LABEL: @t9(
+; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Z:%.*]]
+; CHECK-NEXT:    call void @use8(i8 [[T0]])
+; CHECK-NEXT:    [[T11:%.*]] = add i8 [[Y:%.*]], [[Z]]
+; CHECK-NEXT:    [[T2:%.*]] = add i8 [[T11]], [[X:%.*]]
+; CHECK-NEXT:    ret i8 [[T2]]
+;
+  %t0 = sub i8 0, %z
+  call void @use8(i8 %t0)
+  %t1 = sub i8 %t0, %y
+  %t2 = sub i8 %x, %t1
+  ret i8 %t2
+}
+define i8 @n10(i8 %x, i8 %y, i8 %z) {
+; CHECK-LABEL: @n10(
+; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Z:%.*]]
+; CHECK-NEXT:    call void @use8(i8 [[T0]])
+; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[T0]], [[Y:%.*]]
+; CHECK-NEXT:    call void @use8(i8 [[T1]])
+; CHECK-NEXT:    [[T2:%.*]] = sub i8 [[X:%.*]], [[T1]]
+; CHECK-NEXT:    ret i8 [[T2]]
+;
+  %t0 = sub i8 0, %z
+  call void @use8(i8 %t0)
+  %t1 = sub i8 %t0, %y
+  call void @use8(i8 %t1)
+  %t2 = sub i8 %x, %t1
+  ret i8 %t2
+}
+define i8 @n11(i8 %x, i8 %y, i8 %z) {
+; CHECK-LABEL: @n11(
+; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Z:%.*]]
+; CHECK-NEXT:    call void @use8(i8 [[T0]])
+; CHECK-NEXT:    [[T1:%.*]] = add i8 [[Y:%.*]], [[Z]]
+; CHECK-NEXT:    [[T2:%.*]] = sub i8 [[X:%.*]], [[T1]]
+; CHECK-NEXT:    ret i8 [[T2]]
+;
+  %t0 = sub i8 0, %z
+  call void @use8(i8 %t0)
+  %t1 = sub i8 %y, %t0
+  %t2 = sub i8 %x, %t1
+  ret i8 %t2
+}
+
+; Addition can be negated if both operands can be negated
+; x - (y + z) -> x - y - z -> x + ((-y) + (-z)))
+define i8 @t12(i8 %x, i8 %y, i8 %z) {
+; CHECK-LABEL: @t12(
+; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Y:%.*]]
+; CHECK-NEXT:    call void @use8(i8 [[T0]])
+; CHECK-NEXT:    [[T1:%.*]] = sub i8 0, [[Z:%.*]]
+; CHECK-NEXT:    call void @use8(i8 [[T1]])
+; CHECK-NEXT:    [[TMP1:%.*]] = add i8 [[Y]], [[Z]]
+; CHECK-NEXT:    [[T3:%.*]] = add i8 [[TMP1]], [[X:%.*]]
+; CHECK-NEXT:    ret i8 [[T3]]
+;
+  %t0 = sub i8 0, %y
+  call void @use8(i8 %t0)
+  %t1 = sub i8 0, %z
+  call void @use8(i8 %t1)
+  %t2 = add i8 %t0, %t1
+  %t3 = sub i8 %x, %t2
+  ret i8 %t3
+}
+define i8 @n13(i8 %x, i8 %y, i8 %z) {
+; CHECK-LABEL: @n13(
+; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Y:%.*]]
+; CHECK-NEXT:    call void @use8(i8 [[T0]])
+; CHECK-NEXT:    [[T11:%.*]] = sub i8 [[Y]], [[Z:%.*]]
+; CHECK-NEXT:    [[T2:%.*]] = add i8 [[T11]], [[X:%.*]]
+; CHECK-NEXT:    ret i8 [[T2]]
+;
+  %t0 = sub i8 0, %y
+  call void @use8(i8 %t0)
+  %t1 = add i8 %t0, %z
+  %t2 = sub i8 %x, %t1
+  ret i8 %t2
+}
+define i8 @n14(i8 %x, i8 %y, i8 %z) {
+; CHECK-LABEL: @n14(
+; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Y:%.*]]
+; CHECK-NEXT:    call void @use8(i8 [[T0]])
+; CHECK-NEXT:    [[T1:%.*]] = sub i8 0, [[Z:%.*]]
+; CHECK-NEXT:    call void @use8(i8 [[T1]])
+; CHECK-NEXT:    [[TMP1:%.*]] = add i8 [[Y]], [[Z]]
+; CHECK-NEXT:    [[T2:%.*]] = sub i8 0, [[TMP1]]
+; CHECK-NEXT:    call void @use8(i8 [[T2]])
+; CHECK-NEXT:    [[T3:%.*]] = add i8 [[TMP1]], [[X:%.*]]
+; CHECK-NEXT:    ret i8 [[T3]]
+;
+  %t0 = sub i8 0, %y
+  call void @use8(i8 %t0)
+  %t1 = sub i8 0, %z
+  call void @use8(i8 %t1)
+  %t2 = add i8 %t0, %t1
+  call void @use8(i8 %t2)
+  %t3 = sub i8 %x, %t2
+  ret i8 %t3
+}
+
+; Multiplication can be negated if either one of operands can be negated
+; x - (y * z) -> x + ((-y) * z) or  x + ((-z) * y)
+define i8 @t15(i8 %x, i8 %y, i8 %z) {
+; CHECK-LABEL: @t15(
+; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Y:%.*]]
+; CHECK-NEXT:    call void @use8(i8 [[T0]])
+; CHECK-NEXT:    [[TMP1:%.*]] = mul i8 [[Z:%.*]], [[Y]]
+; CHECK-NEXT:    [[T2:%.*]] = add i8 [[TMP1]], [[X:%.*]]
+; CHECK-NEXT:    ret i8 [[T2]]
+;
+  %t0 = sub i8 0, %y
+  call void @use8(i8 %t0)
+  %t1 = mul i8 %t0, %z
+  %t2 = sub i8 %x, %t1
+  ret i8 %t2
+}
+define i8 @n16(i8 %x, i8 %y, i8 %z) {
+; CHECK-LABEL: @n16(
+; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Y:%.*]]
+; CHECK-NEXT:    call void @use8(i8 [[T0]])
+; CHECK-NEXT:    [[T1:%.*]] = mul i8 [[T0]], [[Z:%.*]]
+; CHECK-NEXT:    call void @use8(i8 [[T1]])
+; CHECK-NEXT:    [[T2:%.*]] = sub i8 [[X:%.*]], [[T1]]
+; CHECK-NEXT:    ret i8 [[T2]]
+;
+  %t0 = sub i8 0, %y
+  call void @use8(i8 %t0)
+  %t1 = mul i8 %t0, %z
+  call void @use8(i8 %t1)
+  %t2 = sub i8 %x, %t1
+  ret i8 %t2
+}




More information about the llvm-commits mailing list