xref: /llvm-project/llvm/test/Transforms/SLPVectorizer/X86/trunc-store-value-ty-not-power-of-2.ll (revision b73476c7843f21966acb2fb5cab8515d9ec02905)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
2; RUN: opt -p slp-vectorizer -S %s | FileCheck %s
3
4target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
5target triple = "x86_64-unknown-linux-gnu"
6
7define void @test_2_i24_stores(ptr %A) {
8; CHECK-LABEL: define void @test_2_i24_stores(
9; CHECK-SAME: ptr [[A:%.*]]) {
10; CHECK-NEXT:    [[L:%.*]] = load i24, ptr [[A]], align 4
11; CHECK-NEXT:    store i24 [[L]], ptr [[A]], align 1
12; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i24, ptr [[A]], i64 1
13; CHECK-NEXT:    store i24 0, ptr [[GEP]], align 1
14; CHECK-NEXT:    ret void
15;
16  %l = load i24, ptr %A
17  store i24 %l, ptr %A, align 1
18  %gep = getelementptr i24, ptr %A, i64 1
19  store i24 0, ptr %gep, align 1
20  ret void
21}
22
23define void @test_2_trunc_i24_to_i8(i24 %x, ptr %A) {
24; CHECK-LABEL: define void @test_2_trunc_i24_to_i8(
25; CHECK-SAME: i24 [[X:%.*]], ptr [[A:%.*]]) {
26; CHECK-NEXT:    [[T:%.*]] = trunc i24 [[X]] to i8
27; CHECK-NEXT:    store i8 [[T]], ptr [[A]], align 1
28; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i8, ptr [[A]], i64 1
29; CHECK-NEXT:    store i8 0, ptr [[GEP]], align 1
30; CHECK-NEXT:    ret void
31;
32  %t = trunc i24 %x to i8
33  store i8 %t, ptr %A, align 1
34  %gep = getelementptr i8, ptr %A, i64 1
35  store i8 0, ptr %gep, align 1
36  ret void
37}
38
39define void @test_4_trunc_i24_to_i8(i24 %x, ptr %A) {
40; CHECK-LABEL: define void @test_4_trunc_i24_to_i8(
41; CHECK-SAME: i24 [[X:%.*]], ptr [[A:%.*]]) {
42; CHECK-NEXT:    [[T:%.*]] = trunc i24 [[X]] to i8
43; CHECK-NEXT:    store i8 [[T]], ptr [[A]], align 1
44; CHECK-NEXT:    [[GEP_1:%.*]] = getelementptr i8, ptr [[A]], i64 1
45; CHECK-NEXT:    store i8 [[T]], ptr [[GEP_1]], align 1
46; CHECK-NEXT:    [[GEP_2:%.*]] = getelementptr i8, ptr [[A]], i64 2
47; CHECK-NEXT:    store i8 [[T]], ptr [[GEP_2]], align 1
48; CHECK-NEXT:    [[GEP_3:%.*]] = getelementptr i8, ptr [[A]], i64 3
49; CHECK-NEXT:    store i8 [[T]], ptr [[GEP_3]], align 1
50; CHECK-NEXT:    ret void
51;
52  %t = trunc i24 %x to i8
53  store i8 %t, ptr %A, align 1
54  %gep.1 = getelementptr i8, ptr %A, i64 1
55  store i8 %t, ptr %gep.1, align 1
56  %gep.2 = getelementptr i8, ptr %A, i64 2
57  store i8 %t, ptr %gep.2, align 1
58  %gep.3 = getelementptr i8, ptr %A, i64 3
59  store i8 %t, ptr %gep.3, align 1
60  ret void
61}
62
63define void @test_8_trunc_i24_to_i8(i24 %x, ptr %A) {
64; CHECK-LABEL: define void @test_8_trunc_i24_to_i8(
65; CHECK-SAME: i24 [[X:%.*]], ptr [[A:%.*]]) {
66; CHECK-NEXT:    [[T:%.*]] = trunc i24 [[X]] to i8
67; CHECK-NEXT:    [[TMP1:%.*]] = insertelement <8 x i8> poison, i8 [[T]], i32 0
68; CHECK-NEXT:    [[TMP2:%.*]] = shufflevector <8 x i8> [[TMP1]], <8 x i8> poison, <8 x i32> zeroinitializer
69; CHECK-NEXT:    store <8 x i8> [[TMP2]], ptr [[A]], align 1
70; CHECK-NEXT:    ret void
71;
72  %t = trunc i24 %x to i8
73  store i8 %t, ptr %A, align 1
74  %gep.1 = getelementptr i8, ptr %A, i64 1
75  store i8 %t, ptr %gep.1, align 1
76  %gep.2 = getelementptr i8, ptr %A, i64 2
77  store i8 %t, ptr %gep.2, align 1
78  %gep.3 = getelementptr i8, ptr %A, i64 3
79  store i8 %t, ptr %gep.3, align 1
80  %gep.4 = getelementptr i8, ptr %A, i64 4
81  store i8 %t, ptr %gep.4, align 1
82  %gep.5 = getelementptr i8, ptr %A, i64 5
83  store i8 %t, ptr %gep.5, align 1
84  %gep.6 = getelementptr i8, ptr %A, i64 6
85  store i8 %t, ptr %gep.6, align 1
86  %gep.7 = getelementptr i8, ptr %A, i64 7
87  store i8 %t, ptr %gep.7, align 1
88  ret void
89}
90
91define void @test_4_trunc_i24_to_i16(i24 %x, ptr %A) {
92; CHECK-LABEL: define void @test_4_trunc_i24_to_i16(
93; CHECK-SAME: i24 [[X:%.*]], ptr [[A:%.*]]) {
94; CHECK-NEXT:    [[T:%.*]] = trunc i24 [[X]] to i16
95; CHECK-NEXT:    [[TMP1:%.*]] = insertelement <4 x i16> poison, i16 [[T]], i32 0
96; CHECK-NEXT:    [[TMP2:%.*]] = shufflevector <4 x i16> [[TMP1]], <4 x i16> poison, <4 x i32> zeroinitializer
97; CHECK-NEXT:    store <4 x i16> [[TMP2]], ptr [[A]], align 1
98; CHECK-NEXT:    ret void
99;
100  %t = trunc i24 %x to i16
101  store i16 %t, ptr %A, align 1
102  %gep.1 = getelementptr i16, ptr %A, i64 1
103  store i16 %t, ptr %gep.1, align 1
104  %gep.2 = getelementptr i16, ptr %A, i64 2
105  store i16 %t, ptr %gep.2, align 1
106  %gep.3 = getelementptr i16, ptr %A, i64 3
107  store i16 %t, ptr %gep.3, align 1
108  ret void
109}
110
111%struct.d = type { [3 x i8], [3 x i8], [2 x i8] }
112
113; Test case for https://github.com/llvm/llvm-project/issues/88640.
114define void @test_access_i24_directly(ptr %src, ptr noalias %dst) "target-cpu"="btver2" {
115; CHECK-LABEL: define void @test_access_i24_directly(
116; CHECK-SAME: ptr [[SRC:%.*]], ptr noalias [[DST:%.*]]) #[[ATTR0:[0-9]+]] {
117; CHECK-NEXT:  entry:
118; CHECK-NEXT:    [[TMP0:%.*]] = load i64, ptr [[SRC]], align 8
119; CHECK-NEXT:    [[TMP1:%.*]] = trunc i64 [[TMP0]] to i24
120; CHECK-NEXT:    [[GEP_SRC:%.*]] = getelementptr inbounds [[STRUCT_D:%.*]], ptr [[SRC]], i64 0, i32 1
121; CHECK-NEXT:    [[BF_LOAD:%.*]] = load i24, ptr [[GEP_SRC]], align 1
122; CHECK-NEXT:    [[BF_VALUE:%.*]] = and i24 [[TMP1]], 8388607
123; CHECK-NEXT:    [[BF_CLEAR:%.*]] = and i24 [[BF_LOAD]], -8388608
124; CHECK-NEXT:    [[BF_SET:%.*]] = or disjoint i24 [[BF_CLEAR]], [[BF_VALUE]]
125; CHECK-NEXT:    [[GEP_DST:%.*]] = getelementptr inbounds [[STRUCT_D]], ptr [[DST]], i64 0, i32 1
126; CHECK-NEXT:    store i24 [[BF_SET]], ptr [[GEP_DST]], align 1
127; CHECK-NEXT:    store i24 0, ptr [[DST]], align 8
128; CHECK-NEXT:    ret void
129;
130entry:
131  %0 = load i64, ptr %src, align 8
132  %1 = trunc i64 %0 to i24
133  %gep.src = getelementptr inbounds %struct.d, ptr %src, i64 0, i32 1
134  %bf.load = load i24, ptr %gep.src, align 1
135  %bf.value = and i24 %1, 8388607
136  %bf.clear = and i24 %bf.load, -8388608
137  %bf.set = or disjoint i24 %bf.clear, %bf.value
138  %gep.dst = getelementptr inbounds %struct.d, ptr %dst, i64 0, i32 1
139  store i24 %bf.set, ptr %gep.dst, align 1
140  store i24 0, ptr %dst, align 8
141  ret void
142}
143