xref: /llvm-project/llvm/test/Transforms/InstCombine/shift-cttz-ctlz.ll (revision a59976bea8ad76f18119a11391dc8ba3e6ba07d5)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
2; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3
4define i32 @shl_cttz_false(i32 %x, i32 %y) {
5; CHECK-LABEL: define i32 @shl_cttz_false(
6; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
7; CHECK-NEXT:  entry:
8; CHECK-NEXT:    [[CTTZ:%.*]] = call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[Y]], i1 true)
9; CHECK-NEXT:    [[RES:%.*]] = shl i32 [[X]], [[CTTZ]]
10; CHECK-NEXT:    ret i32 [[RES]]
11;
12entry:
13  %cttz = call i32 @llvm.cttz.i32(i32 %y, i1 false)
14  %res = shl i32 %x, %cttz
15  ret i32 %res
16}
17
18; Make sure that noundef is dropped.
19
20define i32 @shl_cttz_false_noundef(i32 %x, i32 %y) {
21; CHECK-LABEL: define i32 @shl_cttz_false_noundef(
22; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
23; CHECK-NEXT:  entry:
24; CHECK-NEXT:    [[CTTZ:%.*]] = call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[Y]], i1 true)
25; CHECK-NEXT:    [[RES:%.*]] = shl i32 [[X]], [[CTTZ]]
26; CHECK-NEXT:    ret i32 [[RES]]
27;
28entry:
29  %cttz = call noundef i32 @llvm.cttz.i32(i32 %y, i1 false)
30  %res = shl i32 %x, %cttz
31  ret i32 %res
32}
33
34define i32 @shl_ctlz_false(i32 %x, i32 %y) {
35; CHECK-LABEL: define i32 @shl_ctlz_false(
36; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
37; CHECK-NEXT:  entry:
38; CHECK-NEXT:    [[CTTZ:%.*]] = call range(i32 0, 33) i32 @llvm.ctlz.i32(i32 [[Y]], i1 true)
39; CHECK-NEXT:    [[RES:%.*]] = shl i32 [[X]], [[CTTZ]]
40; CHECK-NEXT:    ret i32 [[RES]]
41;
42entry:
43  %cttz = call i32 @llvm.ctlz.i32(i32 %y, i1 false)
44  %res = shl i32 %x, %cttz
45  ret i32 %res
46}
47
48define i32 @lshr_cttz_false(i32 %x, i32 %y) {
49; CHECK-LABEL: define i32 @lshr_cttz_false(
50; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
51; CHECK-NEXT:  entry:
52; CHECK-NEXT:    [[CTTZ:%.*]] = call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[Y]], i1 true)
53; CHECK-NEXT:    [[RES:%.*]] = lshr i32 [[X]], [[CTTZ]]
54; CHECK-NEXT:    ret i32 [[RES]]
55;
56entry:
57  %cttz = call i32 @llvm.cttz.i32(i32 %y, i1 false)
58  %res = lshr i32 %x, %cttz
59  ret i32 %res
60}
61
62define i32 @ashr_cttz_false(i32 %x, i32 %y) {
63; CHECK-LABEL: define i32 @ashr_cttz_false(
64; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
65; CHECK-NEXT:  entry:
66; CHECK-NEXT:    [[CTTZ:%.*]] = call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[Y]], i1 true)
67; CHECK-NEXT:    [[RES:%.*]] = ashr i32 [[X]], [[CTTZ]]
68; CHECK-NEXT:    ret i32 [[RES]]
69;
70entry:
71  %cttz = call i32 @llvm.cttz.i32(i32 %y, i1 false)
72  %res = ashr i32 %x, %cttz
73  ret i32 %res
74}
75
76define i32 @shl_cttz_false_multiuse(i32 %x, i32 %y) {
77; CHECK-LABEL: define i32 @shl_cttz_false_multiuse(
78; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
79; CHECK-NEXT:  entry:
80; CHECK-NEXT:    [[CTTZ:%.*]] = call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[Y]], i1 false)
81; CHECK-NEXT:    call void @use(i32 [[CTTZ]])
82; CHECK-NEXT:    [[RES:%.*]] = shl i32 [[X]], [[CTTZ]]
83; CHECK-NEXT:    ret i32 [[RES]]
84;
85entry:
86  %cttz = call i32 @llvm.cttz.i32(i32 %y, i1 false)
87  call void @use(i32 %cttz)
88  %res = shl i32 %x, %cttz
89  ret i32 %res
90}
91
92define i32 @shl_cttz_as_lhs(i32 %x, i32 %y) {
93; CHECK-LABEL: define i32 @shl_cttz_as_lhs(
94; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
95; CHECK-NEXT:  entry:
96; CHECK-NEXT:    [[CTTZ:%.*]] = call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[Y]], i1 false)
97; CHECK-NEXT:    [[RES:%.*]] = shl i32 [[CTTZ]], [[X]]
98; CHECK-NEXT:    ret i32 [[RES]]
99;
100entry:
101  %cttz = call i32 @llvm.cttz.i32(i32 %y, i1 false)
102  %res = shl i32 %cttz, %x
103  ret i32 %res
104}
105
106declare void @use(i32)
107