[InstCombine] Signed saturation patterns
[llvm-core.git] / test / Transforms / InstCombine / fold-sub-of-not-to-inc-of-add.ll
blobcf9d051d125bfc7cf15cc1bdea749fc99dfd9f76
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -instcombine -S < %s | FileCheck %s
4 ; Given:
5 ;   sub %y, (xor %x, -1)
6 ; Transform it to:
7 ;   add (add %x, 1), %y
8 ; We prefer this form because that is what -reassociate would produce.
10 ;------------------------------------------------------------------------------;
11 ; Scalar tests
12 ;------------------------------------------------------------------------------;
14 define i32 @p0_scalar(i32 %x, i32 %y) {
15 ; CHECK-LABEL: @p0_scalar(
16 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[Y:%.*]], 1
17 ; CHECK-NEXT:    [[T1:%.*]] = add i32 [[TMP1]], [[X:%.*]]
18 ; CHECK-NEXT:    ret i32 [[T1]]
20   %t0 = xor i32 %x, -1
21   %t1 = sub i32 %y, %t0
22   ret i32 %t1
25 ;------------------------------------------------------------------------------;
26 ; Vector tests
27 ;------------------------------------------------------------------------------;
29 define <4 x i32> @p1_vector_splat(<4 x i32> %x, <4 x i32> %y) {
30 ; CHECK-LABEL: @p1_vector_splat(
31 ; CHECK-NEXT:    [[TMP1:%.*]] = add <4 x i32> [[Y:%.*]], <i32 1, i32 1, i32 1, i32 1>
32 ; CHECK-NEXT:    [[T1:%.*]] = add <4 x i32> [[TMP1]], [[X:%.*]]
33 ; CHECK-NEXT:    ret <4 x i32> [[T1]]
35   %t0 = xor <4 x i32> %x, <i32 -1, i32 -1, i32 -1, i32 -1>
36   %t1 = sub <4 x i32> %y, %t0
37   ret <4 x i32> %t1
40 define <4 x i32> @p2_vector_undef(<4 x i32> %x, <4 x i32> %y) {
41 ; CHECK-LABEL: @p2_vector_undef(
42 ; CHECK-NEXT:    [[TMP1:%.*]] = add <4 x i32> [[Y:%.*]], <i32 1, i32 1, i32 1, i32 1>
43 ; CHECK-NEXT:    [[T1:%.*]] = add <4 x i32> [[TMP1]], [[X:%.*]]
44 ; CHECK-NEXT:    ret <4 x i32> [[T1]]
46   %t0 = xor <4 x i32> %x, <i32 -1, i32 -1, i32 undef, i32 -1>
47   %t1 = sub <4 x i32> %y, %t0
48   ret <4 x i32> %t1
51 ;------------------------------------------------------------------------------;
52 ; One-use test
53 ;------------------------------------------------------------------------------;
55 declare void @use32(i32)
57 define i32 @p3_oneuse(i32 %x, i32 %y) {
58 ; CHECK-LABEL: @p3_oneuse(
59 ; CHECK-NEXT:    [[T0:%.*]] = xor i32 [[X:%.*]], -1
60 ; CHECK-NEXT:    call void @use32(i32 [[T0]])
61 ; CHECK-NEXT:    [[T1:%.*]] = sub i32 [[Y:%.*]], [[T0]]
62 ; CHECK-NEXT:    ret i32 [[T1]]
64   %t0 = xor i32 %x, -1
65   call void @use32(i32 %t0)
66   %t1 = sub i32 %y, %t0
67   ret i32 %t1
70 ;------------------------------------------------------------------------------;
71 ; Basic negative tests
72 ;------------------------------------------------------------------------------;
74 ; The `sub` (and the fold) is not commutative.
75 define i32 @n4(i32 %x, i32 %y) {
76 ; CHECK-LABEL: @n4(
77 ; CHECK-NEXT:    [[T0:%.*]] = xor i32 [[X:%.*]], -1
78 ; CHECK-NEXT:    [[T1:%.*]] = sub i32 [[T0]], [[Y:%.*]]
79 ; CHECK-NEXT:    ret i32 [[T1]]
81   %t0 = xor i32 %x, -1
82   %t1 = sub i32 %t0, %y ; swapped
83   ret i32 %t1
86 define i32 @n5_is_not_not(i32 %x, i32 %y) {
87 ; CHECK-LABEL: @n5_is_not_not(
88 ; CHECK-NEXT:    [[T0:%.*]] = xor i32 [[X:%.*]], 2147483647
89 ; CHECK-NEXT:    [[T1:%.*]] = sub i32 [[Y:%.*]], [[T0]]
90 ; CHECK-NEXT:    ret i32 [[T1]]
92   %t0 = xor i32 %x, 2147483647 ; not -1
93   %t1 = sub i32 %y, %t0
94   ret i32 %t1