xref: /llvm-project/llvm/test/Transforms/InstCombine/and-add-shl.ll (revision 2dd52b4527667837cc525aa48435ab5cbfa30a0b)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
2; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3
4declare void @llvm.assume(i1)
5declare i8 @llvm.ctpop.i8(i8)
6
7; https://alive2.llvm.org/ce/z/LV_8xy
8define i8 @and_add_shl(i8 %x) {
9; CHECK-LABEL: define i8 @and_add_shl
10; CHECK-SAME: (i8 [[X:%.*]]) {
11; CHECK-NEXT:    [[OP1_P2:%.*]] = icmp ult i8 [[X]], 6
12; CHECK-NEXT:    call void @llvm.assume(i1 [[OP1_P2]])
13; CHECK-NEXT:    [[NOTMASK:%.*]] = shl nsw i8 -1, [[X]]
14; CHECK-NEXT:    [[SUB:%.*]] = and i8 [[NOTMASK]], 32
15; CHECK-NEXT:    [[R:%.*]] = xor i8 [[SUB]], 32
16; CHECK-NEXT:    ret i8 [[R]]
17;
18  %op1_p2 = icmp ule i8 %x, 5
19  call void @llvm.assume(i1 %op1_p2)
20  %shift = shl i8 1, %x
21  %sub = add i8 %shift, -1
22  %r = and i8 %sub, 32
23  ret i8 %r
24}
25
26; https://alive2.llvm.org/ce/z/YNYYdV
27define i8 @and_not_shl(i8 %x) {
28; CHECK-LABEL: define i8 @and_not_shl
29; CHECK-SAME: (i8 [[X:%.*]]) {
30; CHECK-NEXT:    [[OP1_P2:%.*]] = icmp ult i8 [[X]], 6
31; CHECK-NEXT:    call void @llvm.assume(i1 [[OP1_P2]])
32; CHECK-NEXT:    [[SHIFT:%.*]] = shl nsw i8 -1, [[X]]
33; CHECK-NEXT:    [[NOT:%.*]] = and i8 [[SHIFT]], 32
34; CHECK-NEXT:    [[R:%.*]] = xor i8 [[NOT]], 32
35; CHECK-NEXT:    ret i8 [[R]]
36;
37  %op1_p2 = icmp ule i8 %x, 5
38  call void @llvm.assume(i1 %op1_p2)
39  %shift = shl i8 -1, %x
40  %not = xor i8 %shift, -1
41  %r = and i8 %not, 32
42  ret i8 %r
43}
44
45; Negative test: https://alive2.llvm.org/ce/z/uWzb4t
46define i8 @and_add_shl_overlap(i8 %x) {
47; CHECK-LABEL: define i8 @and_add_shl_overlap
48; CHECK-SAME: (i8 [[X:%.*]]) {
49; CHECK-NEXT:    [[OP1_P2:%.*]] = icmp ult i8 [[X]], 7
50; CHECK-NEXT:    call void @llvm.assume(i1 [[OP1_P2]])
51; CHECK-NEXT:    [[NOTMASK:%.*]] = shl nsw i8 -1, [[X]]
52; CHECK-NEXT:    [[SUB:%.*]] = and i8 [[NOTMASK]], 32
53; CHECK-NEXT:    [[R:%.*]] = xor i8 [[SUB]], 32
54; CHECK-NEXT:    ret i8 [[R]]
55;
56  %op1_p2 = icmp ule i8 %x, 6
57  call void @llvm.assume(i1 %op1_p2)
58  %shift = shl i8 1, %x
59  %sub = add i8 %shift, -1
60  %r = and i8 %sub, 32
61  ret i8 %r
62}
63