1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes=instcombine -S < %s | FileCheck %s
8 ; We prefer this form because that is what -passes=reassociate would produce.
10 ;------------------------------------------------------------------------------;
12 ;------------------------------------------------------------------------------;
14 define i32 @p0_scalar(i32 %x, i32 %y) {
15 ; CHECK-LABEL: @p0_scalar(
16 ; CHECK-NEXT: [[T0_NEG:%.*]] = add i32 [[X:%.*]], 1
17 ; CHECK-NEXT: [[T1:%.*]] = add i32 [[T0_NEG]], [[Y:%.*]]
18 ; CHECK-NEXT: ret i32 [[T1]]
25 define i8 @p0_scalar_not_truly_negatable(i8 %x, i8 %y) {
26 ; CHECK-LABEL: @p0_scalar_not_truly_negatable(
27 ; CHECK-NEXT: [[XX:%.*]] = xor i8 [[X:%.*]], 123
28 ; CHECK-NEXT: [[YY:%.*]] = xor i8 [[Y:%.*]], 45
29 ; CHECK-NEXT: [[R:%.*]] = sub i8 [[XX]], [[YY]]
30 ; CHECK-NEXT: ret i8 [[R]]
38 ;------------------------------------------------------------------------------;
40 ;------------------------------------------------------------------------------;
42 define <4 x i32> @p1_vector_splat(<4 x i32> %x, <4 x i32> %y) {
43 ; CHECK-LABEL: @p1_vector_splat(
44 ; CHECK-NEXT: [[T0_NEG:%.*]] = add <4 x i32> [[X:%.*]], splat (i32 1)
45 ; CHECK-NEXT: [[T1:%.*]] = add <4 x i32> [[T0_NEG]], [[Y:%.*]]
46 ; CHECK-NEXT: ret <4 x i32> [[T1]]
48 %t0 = xor <4 x i32> %x, <i32 -1, i32 -1, i32 -1, i32 -1>
49 %t1 = sub <4 x i32> %y, %t0
53 define <4 x i32> @p2_vector_poison(<4 x i32> %x, <4 x i32> %y) {
54 ; CHECK-LABEL: @p2_vector_poison(
55 ; CHECK-NEXT: [[T0_NEG:%.*]] = add <4 x i32> [[X:%.*]], splat (i32 1)
56 ; CHECK-NEXT: [[T1:%.*]] = add <4 x i32> [[T0_NEG]], [[Y:%.*]]
57 ; CHECK-NEXT: ret <4 x i32> [[T1]]
59 %t0 = xor <4 x i32> %x, <i32 -1, i32 -1, i32 poison, i32 -1>
60 %t1 = sub <4 x i32> %y, %t0
64 ;------------------------------------------------------------------------------;
66 ;------------------------------------------------------------------------------;
68 declare void @use32(i32)
70 define i32 @p3_oneuse(i32 %x, i32 %y) {
71 ; CHECK-LABEL: @p3_oneuse(
72 ; CHECK-NEXT: [[T0:%.*]] = xor i32 [[X:%.*]], -1
73 ; CHECK-NEXT: call void @use32(i32 [[T0]])
74 ; CHECK-NEXT: [[T1:%.*]] = sub i32 [[Y:%.*]], [[T0]]
75 ; CHECK-NEXT: ret i32 [[T1]]
78 call void @use32(i32 %t0)
83 ;------------------------------------------------------------------------------;
84 ; Basic negative tests
85 ;------------------------------------------------------------------------------;
87 ; The `sub` (and the fold) is not commutative.
88 define i32 @n4(i32 %x, i32 %y) {
90 ; CHECK-NEXT: [[T0:%.*]] = xor i32 [[X:%.*]], -1
91 ; CHECK-NEXT: [[T1:%.*]] = sub i32 [[T0]], [[Y:%.*]]
92 ; CHECK-NEXT: ret i32 [[T1]]
95 %t1 = sub i32 %t0, %y ; swapped
99 define i32 @n5_is_not_not(i32 %x, i32 %y) {
100 ; CHECK-LABEL: @n5_is_not_not(
101 ; CHECK-NEXT: [[T0:%.*]] = xor i32 [[X:%.*]], 2147483647
102 ; CHECK-NEXT: [[T1:%.*]] = sub i32 [[Y:%.*]], [[T0]]
103 ; CHECK-NEXT: ret i32 [[T1]]
105 %t0 = xor i32 %x, 2147483647 ; not -1
106 %t1 = sub i32 %y, %t0
110 define <2 x i32> @n5_is_not_not_vec_splat(<2 x i32> %x, <2 x i32> %y) {
111 ; CHECK-LABEL: @n5_is_not_not_vec_splat(
112 ; CHECK-NEXT: [[T0:%.*]] = xor <2 x i32> [[X:%.*]], splat (i32 2147483647)
113 ; CHECK-NEXT: [[T1:%.*]] = sub <2 x i32> [[Y:%.*]], [[T0]]
114 ; CHECK-NEXT: ret <2 x i32> [[T1]]
116 %t0 = xor <2 x i32> %x, <i32 2147483647, i32 2147483647> ; signmask, but not -1
117 %t1 = sub <2 x i32> %y, %t0