1; RUN: llc -relocation-model=static < %s -O0 -verify-machineinstrs -fast-isel -fast-isel-abort=1 -mattr=-vsx -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr7 | FileCheck %s --check-prefix=ELF64 2; RUN: llc -relocation-model=static < %s -O0 -verify-machineinstrs -fast-isel -fast-isel-abort=1 -mattr=+vsx -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr7 | FileCheck %s --check-prefix=VSX 3; RUN: llc -relocation-model=static < %s -O0 -verify-machineinstrs -fast-isel -fast-isel-abort=1 -mattr=spe -mtriple=powerpc-unknown-linux-gnu -mcpu=e500 | FileCheck %s --check-prefix=SPE 4 5; This test verifies that load/store instructions are properly generated, 6; and that they pass MI verification. 7 8@a = global i8 1, align 1 9@b = global i16 2, align 2 10@c = global i32 4, align 4 11@d = global i64 8, align 8 12@e = global float 1.25, align 4 13@f = global double 3.5, align 8 14 15%struct.s = type<{ i8, i32 }> 16%struct.t = type<{ i8, i64 }> 17 18@g = global %struct.s <{ i8 1, i32 2 }>, align 1 19@h = global %struct.t <{ i8 1, i64 2 }>, align 1 20 21@i = common global [8192 x i64] zeroinitializer, align 8 22 23; load 24 25define i8 @t1() nounwind { 26; ELF64: t1 27 %1 = load i8, i8* @a, align 1 28; ELF64: lbz 29 %2 = add nsw i8 %1, 1 30; ELF64: addi 31 ret i8 %2 32} 33 34define i16 @t2() nounwind { 35; ELF64: t2 36 %1 = load i16, i16* @b, align 2 37; ELF64: lhz 38 %2 = add nsw i16 %1, 1 39; ELF64: addi 40 ret i16 %2 41} 42 43define i32 @t3() nounwind { 44; ELF64: t3 45 %1 = load i32, i32* @c, align 4 46; ELF64: lwz 47 %2 = add nsw i32 %1, 1 48; ELF64: addi 49 ret i32 %2 50} 51 52define i64 @t4() nounwind { 53; ELF64: t4 54 %1 = load i64, i64* @d, align 4 55; ELF64: ld 56 %2 = add nsw i64 %1, 1 57; ELF64: addi 58 ret i64 %2 59} 60 61define float @t5() nounwind { 62; ELF64: t5 63; SPE: t5 64 %1 = load float, float* @e, align 4 65; ELF64: lfs 66; SPE: lwz 67 %2 = fadd float %1, 1.0 68; ELF64: fadds 69; SPE: efsadd 70 ret float %2 71} 72 73define double @t6() nounwind { 74; ELF64: t6 75; SPE: t6 76 %1 = load double, double* @f, align 8 77; ELF64: lfd 78; VSX: lxsdx 79; SPE: evldd 80 %2 = fadd double %1, 1.0 81; ELF64: fadd 82; VSX: xsadddp 83; SPE: efdadd 84 ret double %2 85} 86 87; store 88 89define void @t7(i8 %v) nounwind { 90; ELF64: t7 91 %1 = add nsw i8 %v, 1 92 store i8 %1, i8* @a, align 1 93; ELF64: addis 94; ELF64: addi 95; ELF64: addi 96; ELF64: stb 97 ret void 98} 99 100define void @t8(i16 %v) nounwind { 101; ELF64: t8 102 %1 = add nsw i16 %v, 1 103 store i16 %1, i16* @b, align 2 104; ELF64: addis 105; ELF64: addi 106; ELF64: addi 107; ELF64: sth 108 ret void 109} 110 111define void @t9(i32 %v) nounwind { 112; ELF64: t9 113 %1 = add nsw i32 %v, 1 114 store i32 %1, i32* @c, align 4 115; ELF64: addis 116; ELF64: addi 117; ELF64: addi 118; ELF64: stw 119 ret void 120} 121 122define void @t10(i64 %v) nounwind { 123; ELF64: t10 124 %1 = add nsw i64 %v, 1 125 store i64 %1, i64* @d, align 4 126; ELF64: addis 127; ELF64: addi 128; ELF64: addi 129; ELF64: std 130 ret void 131} 132 133define void @t11(float %v) nounwind { 134; ELF64: t11 135; SPE: t11 136 %1 = fadd float %v, 1.0 137 store float %1, float* @e, align 4 138; ELF64: fadds 139; ELF64: stfs 140; SPE: efsadd 141; SPE: stw 142 ret void 143} 144 145define void @t12(double %v) nounwind { 146; ELF64: t12 147; SPE: t12 148 %1 = fadd double %v, 1.0 149 store double %1, double* @f, align 8 150; ELF64: fadd 151; ELF64: stfd 152; VSX: xsadddp 153; VSX: stxsdx 154; SPE: efdadd 155; SPE: evstdd 156 ret void 157} 158 159;; lwa requires an offset divisible by 4, so we need lwax here. 160define i64 @t13() nounwind { 161; ELF64: t13 162 %1 = load i32, i32* getelementptr inbounds (%struct.s, %struct.s* @g, i32 0, i32 1), align 1 163 %2 = sext i32 %1 to i64 164; ELF64: li 165; ELF64: lwax 166 %3 = add nsw i64 %2, 1 167; ELF64: addi 168 ret i64 %3 169} 170 171;; ld requires an offset divisible by 4, so we need ldx here. 172define i64 @t14() nounwind { 173; ELF64: t14 174 %1 = load i64, i64* getelementptr inbounds (%struct.t, %struct.t* @h, i32 0, i32 1), align 1 175; ELF64: li 176; ELF64: ldx 177 %2 = add nsw i64 %1, 1 178; ELF64: addi 179 ret i64 %2 180} 181 182;; std requires an offset divisible by 4, so we need stdx here. 183define void @t15(i64 %v) nounwind { 184; ELF64: t15 185 %1 = add nsw i64 %v, 1 186 store i64 %1, i64* getelementptr inbounds (%struct.t, %struct.t* @h, i32 0, i32 1), align 1 187; ELF64: addis 188; ELF64: addi 189; ELF64: addi 190; ELF64: li 191; ELF64: stdx 192 ret void 193} 194 195;; ld requires an offset that fits in 16 bits, so we need ldx here. 196define i64 @t16() nounwind { 197; ELF64: t16 198 %1 = load i64, i64* getelementptr inbounds ([8192 x i64], [8192 x i64]* @i, i32 0, i64 5000), align 8 199; ELF64: lis 200; ELF64: ori 201; ELF64: ldx 202 %2 = add nsw i64 %1, 1 203; ELF64: addi 204 ret i64 %2 205} 206 207;; std requires an offset that fits in 16 bits, so we need stdx here. 208define void @t17(i64 %v) nounwind { 209; ELF64: t17 210 %1 = add nsw i64 %v, 1 211 store i64 %1, i64* getelementptr inbounds ([8192 x i64], [8192 x i64]* @i, i32 0, i64 5000), align 8 212; ELF64: addis 213; ELF64: addi 214; ELF64: addi 215; ELF64: lis 216; ELF64: ori 217; ELF64: stdx 218 ret void 219} 220 221