xref: /aosp_15_r20/external/llvm/test/CodeGen/PowerPC/MergeConsecutiveStores.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: llc -march=ppc32 -mtriple=powerpc-unknown-linux-gnu -mattr=+altivec < %s | FileCheck %s
2*9880d681SAndroid Build Coastguard Worker
3*9880d681SAndroid Build Coastguard Worker;; This test ensures that MergeConsecutiveStores does not attempt to
4*9880d681SAndroid Build Coastguard Worker;; merge stores or loads when doing so would result in unaligned
5*9880d681SAndroid Build Coastguard Worker;; memory operations (unless the target supports those, e.g. X86).
6*9880d681SAndroid Build Coastguard Worker
7*9880d681SAndroid Build Coastguard Worker;; This issue happen in other situations for other targets, but PPC
8*9880d681SAndroid Build Coastguard Worker;; with Altivec extensions was chosen for the test because it does not
9*9880d681SAndroid Build Coastguard Worker;; support unaligned access with AltiVec instructions. If the 4
10*9880d681SAndroid Build Coastguard Worker;; load/stores get merged to an v4i32 vector type severely bad code
11*9880d681SAndroid Build Coastguard Worker;; gets generated: it painstakingly copies the values to a temporary
12*9880d681SAndroid Build Coastguard Worker;; location on the stack, with vector ops, in order to then use
13*9880d681SAndroid Build Coastguard Worker;; integer ops to load from the temporary stack location and store to
14*9880d681SAndroid Build Coastguard Worker;; the final location. Yuck!
15*9880d681SAndroid Build Coastguard Worker
16*9880d681SAndroid Build Coastguard Worker%struct.X = type { i32, i32, i32, i32 }
17*9880d681SAndroid Build Coastguard Worker
18*9880d681SAndroid Build Coastguard Worker@fx = common global %struct.X zeroinitializer, align 4
19*9880d681SAndroid Build Coastguard Worker@fy = common global %struct.X zeroinitializer, align 4
20*9880d681SAndroid Build Coastguard Worker
21*9880d681SAndroid Build Coastguard Worker;; In this test case, lvx and stvx instructions should NOT be
22*9880d681SAndroid Build Coastguard Worker;; generated, as the alignment is not sufficient for it to be
23*9880d681SAndroid Build Coastguard Worker;; worthwhile.
24*9880d681SAndroid Build Coastguard Worker
25*9880d681SAndroid Build Coastguard Worker;; CHECK-LABEL: f:
26*9880d681SAndroid Build Coastguard Worker;; CHECK:      lwzu
27*9880d681SAndroid Build Coastguard Worker;; CHECK-NEXT: lwz
28*9880d681SAndroid Build Coastguard Worker;; CHECK-NEXT: lwz
29*9880d681SAndroid Build Coastguard Worker;; CHECK-NEXT: lwz
30*9880d681SAndroid Build Coastguard Worker;; CHECK-NEXT: stwu
31*9880d681SAndroid Build Coastguard Worker;; CHECK-NEXT: stw
32*9880d681SAndroid Build Coastguard Worker;; CHECK-NEXT: stw
33*9880d681SAndroid Build Coastguard Worker;; CHECK-NEXT: stw
34*9880d681SAndroid Build Coastguard Worker;; CHECK-NEXT: blr
35*9880d681SAndroid Build Coastguard Workerdefine void @f() {
36*9880d681SAndroid Build Coastguard Workerentry:
37*9880d681SAndroid Build Coastguard Worker  %0 = load i32, i32* getelementptr inbounds (%struct.X, %struct.X* @fx, i32 0, i32 0), align 4
38*9880d681SAndroid Build Coastguard Worker  %1 = load i32, i32* getelementptr inbounds (%struct.X, %struct.X* @fx, i32 0, i32 1), align 4
39*9880d681SAndroid Build Coastguard Worker  %2 = load i32, i32* getelementptr inbounds (%struct.X, %struct.X* @fx, i32 0, i32 2), align 4
40*9880d681SAndroid Build Coastguard Worker  %3 = load i32, i32* getelementptr inbounds (%struct.X, %struct.X* @fx, i32 0, i32 3), align 4
41*9880d681SAndroid Build Coastguard Worker  store i32 %0, i32* getelementptr inbounds (%struct.X, %struct.X* @fy, i32 0, i32 0), align 4
42*9880d681SAndroid Build Coastguard Worker  store i32 %1, i32* getelementptr inbounds (%struct.X, %struct.X* @fy, i32 0, i32 1), align 4
43*9880d681SAndroid Build Coastguard Worker  store i32 %2, i32* getelementptr inbounds (%struct.X, %struct.X* @fy, i32 0, i32 2), align 4
44*9880d681SAndroid Build Coastguard Worker  store i32 %3, i32* getelementptr inbounds (%struct.X, %struct.X* @fy, i32 0, i32 3), align 4
45*9880d681SAndroid Build Coastguard Worker  ret void
46*9880d681SAndroid Build Coastguard Worker}
47*9880d681SAndroid Build Coastguard Worker
48*9880d681SAndroid Build Coastguard Worker@gx = common global %struct.X zeroinitializer, align 16
49*9880d681SAndroid Build Coastguard Worker@gy = common global %struct.X zeroinitializer, align 16
50*9880d681SAndroid Build Coastguard Worker
51*9880d681SAndroid Build Coastguard Worker;; In this test, lvx and stvx instructions SHOULD be generated, as
52*9880d681SAndroid Build Coastguard Worker;; the 16-byte alignment of the new load/store is acceptable.
53*9880d681SAndroid Build Coastguard Worker;; CHECK-LABEL: g:
54*9880d681SAndroid Build Coastguard Worker;; CHECK: lvx
55*9880d681SAndroid Build Coastguard Worker;; CHECK: stvx
56*9880d681SAndroid Build Coastguard Worker;; CHECK: blr
57*9880d681SAndroid Build Coastguard Workerdefine void @g() {
58*9880d681SAndroid Build Coastguard Workerentry:
59*9880d681SAndroid Build Coastguard Worker  %0 = load i32, i32* getelementptr inbounds (%struct.X, %struct.X* @fx, i32 0, i32 0), align 16
60*9880d681SAndroid Build Coastguard Worker  %1 = load i32, i32* getelementptr inbounds (%struct.X, %struct.X* @fx, i32 0, i32 1), align 4
61*9880d681SAndroid Build Coastguard Worker  %2 = load i32, i32* getelementptr inbounds (%struct.X, %struct.X* @fx, i32 0, i32 2), align 4
62*9880d681SAndroid Build Coastguard Worker  %3 = load i32, i32* getelementptr inbounds (%struct.X, %struct.X* @fx, i32 0, i32 3), align 4
63*9880d681SAndroid Build Coastguard Worker  store i32 %0, i32* getelementptr inbounds (%struct.X, %struct.X* @fy, i32 0, i32 0), align 16
64*9880d681SAndroid Build Coastguard Worker  store i32 %1, i32* getelementptr inbounds (%struct.X, %struct.X* @fy, i32 0, i32 1), align 4
65*9880d681SAndroid Build Coastguard Worker  store i32 %2, i32* getelementptr inbounds (%struct.X, %struct.X* @fy, i32 0, i32 2), align 4
66*9880d681SAndroid Build Coastguard Worker  store i32 %3, i32* getelementptr inbounds (%struct.X, %struct.X* @fy, i32 0, i32 3), align 4
67*9880d681SAndroid Build Coastguard Worker  ret void
68*9880d681SAndroid Build Coastguard Worker}
69