69 lines · plain
1; RUN: llc -verify-machineinstrs -mtriple=powerpc-unknown-linux-gnu -mattr=+altivec < %s | FileCheck %s2 3;; This test ensures that MergeConsecutiveStores does not attempt to4;; merge stores or loads when doing so would result in unaligned5;; memory operations (unless the target supports those, e.g. X86).6 7;; This issue happen in other situations for other targets, but PPC8;; with Altivec extensions was chosen for the test because it does not9;; support unaligned access with AltiVec instructions. If the 410;; load/stores get merged to an v4i32 vector type severely bad code11;; gets generated: it painstakingly copies the values to a temporary12;; location on the stack, with vector ops, in order to then use13;; integer ops to load from the temporary stack location and store to14;; the final location. Yuck!15 16%struct.X = type { i32, i32, i32, i32 }17 18@fx = common global %struct.X zeroinitializer, align 419@fy = common global %struct.X zeroinitializer, align 420 21;; In this test case, lvx and stvx instructions should NOT be22;; generated, as the alignment is not sufficient for it to be23;; worthwhile.24 25;; CHECK-LABEL: f:26;; CHECK-DAG: lwzu27;; CHECK-DAG: stwu28;; CHECK-DAG: lwz29;; CHECK-DAG: lwz30;; CHECK-DAG: lwz31;; CHECK-DAG: stw32;; CHECK-DAG: stw33;; CHECK-DAG: stw34;; CHECK-NEXT: blr35define void @f() {36entry:37 %0 = load i32, ptr @fx, align 438 %1 = load i32, ptr getelementptr inbounds (%struct.X, ptr @fx, i32 0, i32 1), align 439 %2 = load i32, ptr getelementptr inbounds (%struct.X, ptr @fx, i32 0, i32 2), align 440 %3 = load i32, ptr getelementptr inbounds (%struct.X, ptr @fx, i32 0, i32 3), align 441 store i32 %0, ptr @fy, align 442 store i32 %1, ptr getelementptr inbounds (%struct.X, ptr @fy, i32 0, i32 1), align 443 store i32 %2, ptr getelementptr inbounds (%struct.X, ptr @fy, i32 0, i32 2), align 444 store i32 %3, ptr getelementptr inbounds (%struct.X, ptr @fy, i32 0, i32 3), align 445 ret void46}47 48@gx = common global %struct.X zeroinitializer, align 1649@gy = common global %struct.X zeroinitializer, align 1650 51;; In this test, lvx and stvx instructions SHOULD be generated, as52;; the 16-byte alignment of the new load/store is acceptable.53;; CHECK-LABEL: g:54;; CHECK: lvx55;; CHECK: stvx56;; CHECK: blr57define void @g() {58entry:59 %0 = load i32, ptr @fx, align 1660 %1 = load i32, ptr getelementptr inbounds (%struct.X, ptr @fx, i32 0, i32 1), align 461 %2 = load i32, ptr getelementptr inbounds (%struct.X, ptr @fx, i32 0, i32 2), align 462 %3 = load i32, ptr getelementptr inbounds (%struct.X, ptr @fx, i32 0, i32 3), align 463 store i32 %0, ptr @fy, align 1664 store i32 %1, ptr getelementptr inbounds (%struct.X, ptr @fy, i32 0, i32 1), align 465 store i32 %2, ptr getelementptr inbounds (%struct.X, ptr @fy, i32 0, i32 2), align 466 store i32 %3, ptr getelementptr inbounds (%struct.X, ptr @fy, i32 0, i32 3), align 467 ret void68}69