[AArch64][NFC] NFC for const vector as Instruction operand (#116790)
[llvm-project.git] / llvm / test / Transforms / InstCombine / add-mask-neg.ll
blobcb23763249d6365a8c0c62f1b9f1b0e00f647656
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -S -passes=instcombine | FileCheck %s
5 ; Canonicalize ((X & -X) - 1) --> ((X - 1) & ~X)
8 define i32 @dec_mask_neg_i32(i32 %X) {
9 ; CHECK-LABEL: @dec_mask_neg_i32(
10 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[X:%.*]], -1
11 ; CHECK-NEXT:    [[TMP2:%.*]] = xor i32 [[X]], -1
12 ; CHECK-NEXT:    [[DEC:%.*]] = and i32 [[TMP1]], [[TMP2]]
13 ; CHECK-NEXT:    ret i32 [[DEC]]
15   %neg = sub i32 0, %X
16   %mask = and i32 %neg, %X
17   %dec = add i32 %mask, -1
18   ret i32 %dec
21 define i32 @dec_mask_commute_neg_i32(i32 %A) {
22 ; CHECK-LABEL: @dec_mask_commute_neg_i32(
23 ; CHECK-NEXT:    [[X:%.*]] = sdiv i32 42, [[A:%.*]]
24 ; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i32 [[X]], -1
25 ; CHECK-NEXT:    [[TMP2:%.*]] = xor i32 [[X]], -1
26 ; CHECK-NEXT:    [[DEC:%.*]] = and i32 [[TMP1]], [[TMP2]]
27 ; CHECK-NEXT:    ret i32 [[DEC]]
29   %X = sdiv i32 42, %A ; thwart complexity-based canonicalization
30   %neg = sub i32 0, %X
31   %mask = and i32 %X, %neg
32   %dec = add i32 %mask, -1
33   ret i32 %dec
36 define i32 @dec_commute_mask_neg_i32(i32 %X) {
37 ; CHECK-LABEL: @dec_commute_mask_neg_i32(
38 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[X:%.*]], -1
39 ; CHECK-NEXT:    [[TMP2:%.*]] = xor i32 [[X]], -1
40 ; CHECK-NEXT:    [[DEC:%.*]] = and i32 [[TMP1]], [[TMP2]]
41 ; CHECK-NEXT:    ret i32 [[DEC]]
43   %neg = sub i32 0, %X
44   %mask = and i32 %neg, %X
45   %dec = add i32 -1, %mask
46   ret i32 %dec
49 define i32 @dec_mask_neg_multiuse_i32(i32 %X) {
50 ; CHECK-LABEL: @dec_mask_neg_multiuse_i32(
51 ; CHECK-NEXT:    [[NEG:%.*]] = sub i32 0, [[X:%.*]]
52 ; CHECK-NEXT:    [[MASK:%.*]] = and i32 [[X]], [[NEG]]
53 ; CHECK-NEXT:    [[DEC:%.*]] = add i32 [[MASK]], -1
54 ; CHECK-NEXT:    call void @use(i32 [[NEG]])
55 ; CHECK-NEXT:    ret i32 [[DEC]]
57   %neg = sub i32 0, %X
58   %mask = and i32 %neg, %X
59   %dec = add i32 %mask, -1
60   call void @use(i32 %neg)
61   ret i32 %dec
64 define i32 @dec_mask_multiuse_neg_i32(i32 %X) {
65 ; CHECK-LABEL: @dec_mask_multiuse_neg_i32(
66 ; CHECK-NEXT:    [[NEG:%.*]] = sub i32 0, [[X:%.*]]
67 ; CHECK-NEXT:    [[MASK:%.*]] = and i32 [[X]], [[NEG]]
68 ; CHECK-NEXT:    [[DEC:%.*]] = add i32 [[MASK]], -1
69 ; CHECK-NEXT:    call void @use(i32 [[MASK]])
70 ; CHECK-NEXT:    ret i32 [[DEC]]
72   %neg = sub i32 0, %X
73   %mask = and i32 %neg, %X
74   %dec = add i32 %mask, -1
75   call void @use(i32 %mask)
76   ret i32 %dec
79 define <2 x i32> @dec_mask_neg_v2i32(<2 x i32> %X) {
80 ; CHECK-LABEL: @dec_mask_neg_v2i32(
81 ; CHECK-NEXT:    [[TMP1:%.*]] = add <2 x i32> [[X:%.*]], splat (i32 -1)
82 ; CHECK-NEXT:    [[TMP2:%.*]] = xor <2 x i32> [[X]], splat (i32 -1)
83 ; CHECK-NEXT:    [[DEC:%.*]] = and <2 x i32> [[TMP1]], [[TMP2]]
84 ; CHECK-NEXT:    ret <2 x i32> [[DEC]]
86   %neg = sub <2 x i32> zeroinitializer, %X
87   %mask = and <2 x i32> %neg, %X
88   %dec = add <2 x i32> %mask, <i32 -1, i32 -1>
89   ret <2 x i32> %dec
92 define <2 x i32> @dec_mask_neg_v2i32_poison(<2 x i32> %X) {
93 ; CHECK-LABEL: @dec_mask_neg_v2i32_poison(
94 ; CHECK-NEXT:    [[TMP1:%.*]] = add <2 x i32> [[X:%.*]], splat (i32 -1)
95 ; CHECK-NEXT:    [[TMP2:%.*]] = xor <2 x i32> [[X]], splat (i32 -1)
96 ; CHECK-NEXT:    [[DEC:%.*]] = and <2 x i32> [[TMP1]], [[TMP2]]
97 ; CHECK-NEXT:    ret <2 x i32> [[DEC]]
99   %neg = sub <2 x i32> zeroinitializer, %X
100   %mask = and <2 x i32> %neg, %X
101   %dec = add <2 x i32> %mask, <i32 -1, i32 poison>
102   ret <2 x i32> %dec
105 define <2 x i32> @dec_mask_multiuse_neg_multiuse_v2i32(<2 x i32> %X) {
106 ; CHECK-LABEL: @dec_mask_multiuse_neg_multiuse_v2i32(
107 ; CHECK-NEXT:    [[NEG:%.*]] = sub <2 x i32> zeroinitializer, [[X:%.*]]
108 ; CHECK-NEXT:    [[MASK:%.*]] = and <2 x i32> [[X]], [[NEG]]
109 ; CHECK-NEXT:    [[DEC:%.*]] = add <2 x i32> [[MASK]], splat (i32 -1)
110 ; CHECK-NEXT:    call void @usev(<2 x i32> [[NEG]])
111 ; CHECK-NEXT:    call void @usev(<2 x i32> [[MASK]])
112 ; CHECK-NEXT:    ret <2 x i32> [[DEC]]
114   %neg = sub <2 x i32> zeroinitializer, %X
115   %mask = and <2 x i32> %neg, %X
116   %dec = add <2 x i32> %mask, <i32 -1, i32 -1>
117   call void @usev(<2 x i32> %neg)
118   call void @usev(<2 x i32> %mask)
119   ret <2 x i32> %dec
122 declare void @use(i32)
123 declare void @usev(<2 x i32>)