[DAGCombiner] Add target hook function to decide folding (mul (add x, c1), c2)
[llvm-project.git] / llvm / test / Transforms / InstCombine / shl-demand.ll
blob11c2de8e58d75f4fd1ee32c854b95619c8e72350
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -instcombine -S < %s | FileCheck %s
4 define i16 @sext_shl_trunc_same_size(i16 %x, i32 %y) {
5 ; CHECK-LABEL: @sext_shl_trunc_same_size(
6 ; CHECK-NEXT:    [[CONV1:%.*]] = zext i16 [[X:%.*]] to i32
7 ; CHECK-NEXT:    [[SHL:%.*]] = shl i32 [[CONV1]], [[Y:%.*]]
8 ; CHECK-NEXT:    [[T:%.*]] = trunc i32 [[SHL]] to i16
9 ; CHECK-NEXT:    ret i16 [[T]]
11   %conv = sext i16 %x to i32
12   %shl = shl i32 %conv, %y
13   %t = trunc i32 %shl to i16
14   ret i16 %t
17 define i5 @sext_shl_trunc_smaller(i16 %x, i32 %y) {
18 ; CHECK-LABEL: @sext_shl_trunc_smaller(
19 ; CHECK-NEXT:    [[CONV1:%.*]] = zext i16 [[X:%.*]] to i32
20 ; CHECK-NEXT:    [[SHL:%.*]] = shl i32 [[CONV1]], [[Y:%.*]]
21 ; CHECK-NEXT:    [[T:%.*]] = trunc i32 [[SHL]] to i5
22 ; CHECK-NEXT:    ret i5 [[T]]
24   %conv = sext i16 %x to i32
25   %shl = shl i32 %conv, %y
26   %t = trunc i32 %shl to i5
27   ret i5 %t
30 ; negative test - demanding 1 high-bit too many to change the extend
32 define i17 @sext_shl_trunc_larger(i16 %x, i32 %y) {
33 ; CHECK-LABEL: @sext_shl_trunc_larger(
34 ; CHECK-NEXT:    [[CONV:%.*]] = sext i16 [[X:%.*]] to i32
35 ; CHECK-NEXT:    [[SHL:%.*]] = shl i32 [[CONV]], [[Y:%.*]]
36 ; CHECK-NEXT:    [[T:%.*]] = trunc i32 [[SHL]] to i17
37 ; CHECK-NEXT:    ret i17 [[T]]
39   %conv = sext i16 %x to i32
40   %shl = shl i32 %conv, %y
41   %t = trunc i32 %shl to i17
42   ret i17 %t
45 define i32 @sext_shl_mask(i16 %x, i32 %y) {
46 ; CHECK-LABEL: @sext_shl_mask(
47 ; CHECK-NEXT:    [[CONV1:%.*]] = zext i16 [[X:%.*]] to i32
48 ; CHECK-NEXT:    [[SHL:%.*]] = shl i32 [[CONV1]], [[Y:%.*]]
49 ; CHECK-NEXT:    [[T:%.*]] = and i32 [[SHL]], 65535
50 ; CHECK-NEXT:    ret i32 [[T]]
52   %conv = sext i16 %x to i32
53   %shl = shl i32 %conv, %y
54   %t = and i32 %shl, 65535
55   ret i32 %t
58 ; negative test - demanding a bit that could change with sext
60 define i32 @sext_shl_mask_higher(i16 %x, i32 %y) {
61 ; CHECK-LABEL: @sext_shl_mask_higher(
62 ; CHECK-NEXT:    [[CONV:%.*]] = sext i16 [[X:%.*]] to i32
63 ; CHECK-NEXT:    [[SHL:%.*]] = shl i32 [[CONV]], [[Y:%.*]]
64 ; CHECK-NEXT:    [[T:%.*]] = and i32 [[SHL]], 65536
65 ; CHECK-NEXT:    ret i32 [[T]]
67   %conv = sext i16 %x to i32
68   %shl = shl i32 %conv, %y
69   %t = and i32 %shl, 65536
70   ret i32 %t
73 ; May need some, but not all of the bits set by the 'or'.
75 define i32 @set_shl_mask(i32 %x, i32 %y) {
76 ; CHECK-LABEL: @set_shl_mask(
77 ; CHECK-NEXT:    [[Z:%.*]] = or i32 [[X:%.*]], 65537
78 ; CHECK-NEXT:    [[S:%.*]] = shl i32 [[Z]], [[Y:%.*]]
79 ; CHECK-NEXT:    [[R:%.*]] = and i32 [[S]], 65536
80 ; CHECK-NEXT:    ret i32 [[R]]
82   %z = or i32 %x, 196609
83   %s = shl i32 %z, %y
84   %r = and i32 %s, 65536
85   ret i32 %r
88 ; PR50341
90 define i8 @must_drop_poison(i32 %x, i32 %y)  {
91 ; CHECK-LABEL: @must_drop_poison(
92 ; CHECK-NEXT:    [[S:%.*]] = shl i32 [[X:%.*]], [[Y:%.*]]
93 ; CHECK-NEXT:    [[T:%.*]] = trunc i32 [[S]] to i8
94 ; CHECK-NEXT:    ret i8 [[T]]
96   %a = and i32 %x, 255
97   %s = shl nuw nsw i32 %a, %y
98   %t = trunc i32 %s to i8
99   ret i8 %t