1*9880d681SAndroid Build Coastguard Worker; RUN: llc -verify-machineinstrs -o - %s -mtriple=aarch64-linux-gnu | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu -mattr=-fp-armv8 | FileCheck --check-prefix=CHECK-NOFP %s 3*9880d681SAndroid Build Coastguard Worker 4*9880d681SAndroid Build Coastguard Worker@var_8bit = global i8 0 5*9880d681SAndroid Build Coastguard Worker@var_16bit = global i16 0 6*9880d681SAndroid Build Coastguard Worker@var_32bit = global i32 0 7*9880d681SAndroid Build Coastguard Worker@var_64bit = global i64 0 8*9880d681SAndroid Build Coastguard Worker 9*9880d681SAndroid Build Coastguard Worker@var_float = global float 0.0 10*9880d681SAndroid Build Coastguard Worker@var_double = global double 0.0 11*9880d681SAndroid Build Coastguard Worker 12*9880d681SAndroid Build Coastguard Worker@varptr = global i8* null 13*9880d681SAndroid Build Coastguard Worker 14*9880d681SAndroid Build Coastguard Workerdefine void @ldst_8bit() { 15*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: ldst_8bit: 16*9880d681SAndroid Build Coastguard Worker 17*9880d681SAndroid Build Coastguard Worker; No architectural support for loads to 16-bit or 8-bit since we 18*9880d681SAndroid Build Coastguard Worker; promote i8 during lowering. 19*9880d681SAndroid Build Coastguard Worker %addr_8bit = load i8*, i8** @varptr 20*9880d681SAndroid Build Coastguard Worker 21*9880d681SAndroid Build Coastguard Worker; match a sign-extending load 8-bit -> 32-bit 22*9880d681SAndroid Build Coastguard Worker %addr_sext32 = getelementptr i8, i8* %addr_8bit, i64 -256 23*9880d681SAndroid Build Coastguard Worker %val8_sext32 = load volatile i8, i8* %addr_sext32 24*9880d681SAndroid Build Coastguard Worker %val32_signed = sext i8 %val8_sext32 to i32 25*9880d681SAndroid Build Coastguard Worker store volatile i32 %val32_signed, i32* @var_32bit 26*9880d681SAndroid Build Coastguard Worker; CHECK: ldursb {{w[0-9]+}}, [{{x[0-9]+}}, #-256] 27*9880d681SAndroid Build Coastguard Worker 28*9880d681SAndroid Build Coastguard Worker; match a zero-extending load volatile 8-bit -> 32-bit 29*9880d681SAndroid Build Coastguard Worker %addr_zext32 = getelementptr i8, i8* %addr_8bit, i64 -12 30*9880d681SAndroid Build Coastguard Worker %val8_zext32 = load volatile i8, i8* %addr_zext32 31*9880d681SAndroid Build Coastguard Worker %val32_unsigned = zext i8 %val8_zext32 to i32 32*9880d681SAndroid Build Coastguard Worker store volatile i32 %val32_unsigned, i32* @var_32bit 33*9880d681SAndroid Build Coastguard Worker; CHECK: ldurb {{w[0-9]+}}, [{{x[0-9]+}}, #-12] 34*9880d681SAndroid Build Coastguard Worker 35*9880d681SAndroid Build Coastguard Worker; match an any-extending load volatile 8-bit -> 32-bit 36*9880d681SAndroid Build Coastguard Worker %addr_anyext = getelementptr i8, i8* %addr_8bit, i64 -1 37*9880d681SAndroid Build Coastguard Worker %val8_anyext = load volatile i8, i8* %addr_anyext 38*9880d681SAndroid Build Coastguard Worker %newval8 = add i8 %val8_anyext, 1 39*9880d681SAndroid Build Coastguard Worker store volatile i8 %newval8, i8* @var_8bit 40*9880d681SAndroid Build Coastguard Worker; CHECK: ldurb {{w[0-9]+}}, [{{x[0-9]+}}, #-1] 41*9880d681SAndroid Build Coastguard Worker 42*9880d681SAndroid Build Coastguard Worker; match a sign-extending load volatile 8-bit -> 64-bit 43*9880d681SAndroid Build Coastguard Worker %addr_sext64 = getelementptr i8, i8* %addr_8bit, i64 -5 44*9880d681SAndroid Build Coastguard Worker %val8_sext64 = load volatile i8, i8* %addr_sext64 45*9880d681SAndroid Build Coastguard Worker %val64_signed = sext i8 %val8_sext64 to i64 46*9880d681SAndroid Build Coastguard Worker store volatile i64 %val64_signed, i64* @var_64bit 47*9880d681SAndroid Build Coastguard Worker; CHECK: ldursb {{x[0-9]+}}, [{{x[0-9]+}}, #-5] 48*9880d681SAndroid Build Coastguard Worker 49*9880d681SAndroid Build Coastguard Worker; match a zero-extending load volatile 8-bit -> 64-bit. 50*9880d681SAndroid Build Coastguard Worker; This uses the fact that ldrb w0, [x0] will zero out the high 32-bits 51*9880d681SAndroid Build Coastguard Worker; of x0 so it's identical to load volatileing to 32-bits. 52*9880d681SAndroid Build Coastguard Worker %addr_zext64 = getelementptr i8, i8* %addr_8bit, i64 -9 53*9880d681SAndroid Build Coastguard Worker %val8_zext64 = load volatile i8, i8* %addr_zext64 54*9880d681SAndroid Build Coastguard Worker %val64_unsigned = zext i8 %val8_zext64 to i64 55*9880d681SAndroid Build Coastguard Worker store volatile i64 %val64_unsigned, i64* @var_64bit 56*9880d681SAndroid Build Coastguard Worker; CHECK: ldurb {{w[0-9]+}}, [{{x[0-9]+}}, #-9] 57*9880d681SAndroid Build Coastguard Worker 58*9880d681SAndroid Build Coastguard Worker; truncating store volatile 32-bits to 8-bits 59*9880d681SAndroid Build Coastguard Worker %addr_trunc32 = getelementptr i8, i8* %addr_8bit, i64 -256 60*9880d681SAndroid Build Coastguard Worker %val32 = load volatile i32, i32* @var_32bit 61*9880d681SAndroid Build Coastguard Worker %val8_trunc32 = trunc i32 %val32 to i8 62*9880d681SAndroid Build Coastguard Worker store volatile i8 %val8_trunc32, i8* %addr_trunc32 63*9880d681SAndroid Build Coastguard Worker; CHECK: sturb {{w[0-9]+}}, [{{x[0-9]+}}, #-256] 64*9880d681SAndroid Build Coastguard Worker 65*9880d681SAndroid Build Coastguard Worker; truncating store volatile 64-bits to 8-bits 66*9880d681SAndroid Build Coastguard Worker %addr_trunc64 = getelementptr i8, i8* %addr_8bit, i64 -1 67*9880d681SAndroid Build Coastguard Worker %val64 = load volatile i64, i64* @var_64bit 68*9880d681SAndroid Build Coastguard Worker %val8_trunc64 = trunc i64 %val64 to i8 69*9880d681SAndroid Build Coastguard Worker store volatile i8 %val8_trunc64, i8* %addr_trunc64 70*9880d681SAndroid Build Coastguard Worker; CHECK: sturb {{w[0-9]+}}, [{{x[0-9]+}}, #-1] 71*9880d681SAndroid Build Coastguard Worker 72*9880d681SAndroid Build Coastguard Worker ret void 73*9880d681SAndroid Build Coastguard Worker} 74*9880d681SAndroid Build Coastguard Worker 75*9880d681SAndroid Build Coastguard Workerdefine void @ldst_16bit() { 76*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: ldst_16bit: 77*9880d681SAndroid Build Coastguard Worker 78*9880d681SAndroid Build Coastguard Worker; No architectural support for loads to 16-bit or 16-bit since we 79*9880d681SAndroid Build Coastguard Worker; promote i16 during lowering. 80*9880d681SAndroid Build Coastguard Worker %addr_8bit = load i8*, i8** @varptr 81*9880d681SAndroid Build Coastguard Worker 82*9880d681SAndroid Build Coastguard Worker; match a sign-extending load 16-bit -> 32-bit 83*9880d681SAndroid Build Coastguard Worker %addr8_sext32 = getelementptr i8, i8* %addr_8bit, i64 -256 84*9880d681SAndroid Build Coastguard Worker %addr_sext32 = bitcast i8* %addr8_sext32 to i16* 85*9880d681SAndroid Build Coastguard Worker %val16_sext32 = load volatile i16, i16* %addr_sext32 86*9880d681SAndroid Build Coastguard Worker %val32_signed = sext i16 %val16_sext32 to i32 87*9880d681SAndroid Build Coastguard Worker store volatile i32 %val32_signed, i32* @var_32bit 88*9880d681SAndroid Build Coastguard Worker; CHECK: ldursh {{w[0-9]+}}, [{{x[0-9]+}}, #-256] 89*9880d681SAndroid Build Coastguard Worker 90*9880d681SAndroid Build Coastguard Worker; match a zero-extending load volatile 16-bit -> 32-bit. With offset that would be unaligned. 91*9880d681SAndroid Build Coastguard Worker %addr8_zext32 = getelementptr i8, i8* %addr_8bit, i64 15 92*9880d681SAndroid Build Coastguard Worker %addr_zext32 = bitcast i8* %addr8_zext32 to i16* 93*9880d681SAndroid Build Coastguard Worker %val16_zext32 = load volatile i16, i16* %addr_zext32 94*9880d681SAndroid Build Coastguard Worker %val32_unsigned = zext i16 %val16_zext32 to i32 95*9880d681SAndroid Build Coastguard Worker store volatile i32 %val32_unsigned, i32* @var_32bit 96*9880d681SAndroid Build Coastguard Worker; CHECK: ldurh {{w[0-9]+}}, [{{x[0-9]+}}, #15] 97*9880d681SAndroid Build Coastguard Worker 98*9880d681SAndroid Build Coastguard Worker; match an any-extending load volatile 16-bit -> 32-bit 99*9880d681SAndroid Build Coastguard Worker %addr8_anyext = getelementptr i8, i8* %addr_8bit, i64 -1 100*9880d681SAndroid Build Coastguard Worker %addr_anyext = bitcast i8* %addr8_anyext to i16* 101*9880d681SAndroid Build Coastguard Worker %val16_anyext = load volatile i16, i16* %addr_anyext 102*9880d681SAndroid Build Coastguard Worker %newval16 = add i16 %val16_anyext, 1 103*9880d681SAndroid Build Coastguard Worker store volatile i16 %newval16, i16* @var_16bit 104*9880d681SAndroid Build Coastguard Worker; CHECK: ldurh {{w[0-9]+}}, [{{x[0-9]+}}, #-1] 105*9880d681SAndroid Build Coastguard Worker 106*9880d681SAndroid Build Coastguard Worker; match a sign-extending load volatile 16-bit -> 64-bit 107*9880d681SAndroid Build Coastguard Worker %addr8_sext64 = getelementptr i8, i8* %addr_8bit, i64 -5 108*9880d681SAndroid Build Coastguard Worker %addr_sext64 = bitcast i8* %addr8_sext64 to i16* 109*9880d681SAndroid Build Coastguard Worker %val16_sext64 = load volatile i16, i16* %addr_sext64 110*9880d681SAndroid Build Coastguard Worker %val64_signed = sext i16 %val16_sext64 to i64 111*9880d681SAndroid Build Coastguard Worker store volatile i64 %val64_signed, i64* @var_64bit 112*9880d681SAndroid Build Coastguard Worker; CHECK: ldursh {{x[0-9]+}}, [{{x[0-9]+}}, #-5] 113*9880d681SAndroid Build Coastguard Worker 114*9880d681SAndroid Build Coastguard Worker; match a zero-extending load volatile 16-bit -> 64-bit. 115*9880d681SAndroid Build Coastguard Worker; This uses the fact that ldrb w0, [x0] will zero out the high 32-bits 116*9880d681SAndroid Build Coastguard Worker; of x0 so it's identical to load volatileing to 32-bits. 117*9880d681SAndroid Build Coastguard Worker %addr8_zext64 = getelementptr i8, i8* %addr_8bit, i64 9 118*9880d681SAndroid Build Coastguard Worker %addr_zext64 = bitcast i8* %addr8_zext64 to i16* 119*9880d681SAndroid Build Coastguard Worker %val16_zext64 = load volatile i16, i16* %addr_zext64 120*9880d681SAndroid Build Coastguard Worker %val64_unsigned = zext i16 %val16_zext64 to i64 121*9880d681SAndroid Build Coastguard Worker store volatile i64 %val64_unsigned, i64* @var_64bit 122*9880d681SAndroid Build Coastguard Worker; CHECK: ldurh {{w[0-9]+}}, [{{x[0-9]+}}, #9] 123*9880d681SAndroid Build Coastguard Worker 124*9880d681SAndroid Build Coastguard Worker; truncating store volatile 32-bits to 16-bits 125*9880d681SAndroid Build Coastguard Worker %addr8_trunc32 = getelementptr i8, i8* %addr_8bit, i64 -256 126*9880d681SAndroid Build Coastguard Worker %addr_trunc32 = bitcast i8* %addr8_trunc32 to i16* 127*9880d681SAndroid Build Coastguard Worker %val32 = load volatile i32, i32* @var_32bit 128*9880d681SAndroid Build Coastguard Worker %val16_trunc32 = trunc i32 %val32 to i16 129*9880d681SAndroid Build Coastguard Worker store volatile i16 %val16_trunc32, i16* %addr_trunc32 130*9880d681SAndroid Build Coastguard Worker; CHECK: sturh {{w[0-9]+}}, [{{x[0-9]+}}, #-256] 131*9880d681SAndroid Build Coastguard Worker 132*9880d681SAndroid Build Coastguard Worker; truncating store volatile 64-bits to 16-bits 133*9880d681SAndroid Build Coastguard Worker %addr8_trunc64 = getelementptr i8, i8* %addr_8bit, i64 -1 134*9880d681SAndroid Build Coastguard Worker %addr_trunc64 = bitcast i8* %addr8_trunc64 to i16* 135*9880d681SAndroid Build Coastguard Worker %val64 = load volatile i64, i64* @var_64bit 136*9880d681SAndroid Build Coastguard Worker %val16_trunc64 = trunc i64 %val64 to i16 137*9880d681SAndroid Build Coastguard Worker store volatile i16 %val16_trunc64, i16* %addr_trunc64 138*9880d681SAndroid Build Coastguard Worker; CHECK: sturh {{w[0-9]+}}, [{{x[0-9]+}}, #-1] 139*9880d681SAndroid Build Coastguard Worker 140*9880d681SAndroid Build Coastguard Worker ret void 141*9880d681SAndroid Build Coastguard Worker} 142*9880d681SAndroid Build Coastguard Worker 143*9880d681SAndroid Build Coastguard Workerdefine void @ldst_32bit() { 144*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: ldst_32bit: 145*9880d681SAndroid Build Coastguard Worker 146*9880d681SAndroid Build Coastguard Worker %addr_8bit = load i8*, i8** @varptr 147*9880d681SAndroid Build Coastguard Worker 148*9880d681SAndroid Build Coastguard Worker; Straight 32-bit load/store 149*9880d681SAndroid Build Coastguard Worker %addr32_8_noext = getelementptr i8, i8* %addr_8bit, i64 1 150*9880d681SAndroid Build Coastguard Worker %addr32_noext = bitcast i8* %addr32_8_noext to i32* 151*9880d681SAndroid Build Coastguard Worker %val32_noext = load volatile i32, i32* %addr32_noext 152*9880d681SAndroid Build Coastguard Worker store volatile i32 %val32_noext, i32* %addr32_noext 153*9880d681SAndroid Build Coastguard Worker; CHECK: ldur {{w[0-9]+}}, [{{x[0-9]+}}, #1] 154*9880d681SAndroid Build Coastguard Worker; CHECK: stur {{w[0-9]+}}, [{{x[0-9]+}}, #1] 155*9880d681SAndroid Build Coastguard Worker 156*9880d681SAndroid Build Coastguard Worker; Zero-extension to 64-bits 157*9880d681SAndroid Build Coastguard Worker %addr32_8_zext = getelementptr i8, i8* %addr_8bit, i64 -256 158*9880d681SAndroid Build Coastguard Worker %addr32_zext = bitcast i8* %addr32_8_zext to i32* 159*9880d681SAndroid Build Coastguard Worker %val32_zext = load volatile i32, i32* %addr32_zext 160*9880d681SAndroid Build Coastguard Worker %val64_unsigned = zext i32 %val32_zext to i64 161*9880d681SAndroid Build Coastguard Worker store volatile i64 %val64_unsigned, i64* @var_64bit 162*9880d681SAndroid Build Coastguard Worker; CHECK: ldur {{w[0-9]+}}, [{{x[0-9]+}}, #-256] 163*9880d681SAndroid Build Coastguard Worker; CHECK: str {{x[0-9]+}}, [{{x[0-9]+}}, {{#?}}:lo12:var_64bit] 164*9880d681SAndroid Build Coastguard Worker 165*9880d681SAndroid Build Coastguard Worker; Sign-extension to 64-bits 166*9880d681SAndroid Build Coastguard Worker %addr32_8_sext = getelementptr i8, i8* %addr_8bit, i64 -12 167*9880d681SAndroid Build Coastguard Worker %addr32_sext = bitcast i8* %addr32_8_sext to i32* 168*9880d681SAndroid Build Coastguard Worker %val32_sext = load volatile i32, i32* %addr32_sext 169*9880d681SAndroid Build Coastguard Worker %val64_signed = sext i32 %val32_sext to i64 170*9880d681SAndroid Build Coastguard Worker store volatile i64 %val64_signed, i64* @var_64bit 171*9880d681SAndroid Build Coastguard Worker; CHECK: ldursw {{x[0-9]+}}, [{{x[0-9]+}}, #-12] 172*9880d681SAndroid Build Coastguard Worker; CHECK: str {{x[0-9]+}}, [{{x[0-9]+}}, {{#?}}:lo12:var_64bit] 173*9880d681SAndroid Build Coastguard Worker 174*9880d681SAndroid Build Coastguard Worker; Truncation from 64-bits 175*9880d681SAndroid Build Coastguard Worker %addr64_8_trunc = getelementptr i8, i8* %addr_8bit, i64 255 176*9880d681SAndroid Build Coastguard Worker %addr64_trunc = bitcast i8* %addr64_8_trunc to i64* 177*9880d681SAndroid Build Coastguard Worker %addr32_8_trunc = getelementptr i8, i8* %addr_8bit, i64 -20 178*9880d681SAndroid Build Coastguard Worker %addr32_trunc = bitcast i8* %addr32_8_trunc to i32* 179*9880d681SAndroid Build Coastguard Worker 180*9880d681SAndroid Build Coastguard Worker %val64_trunc = load volatile i64, i64* %addr64_trunc 181*9880d681SAndroid Build Coastguard Worker %val32_trunc = trunc i64 %val64_trunc to i32 182*9880d681SAndroid Build Coastguard Worker store volatile i32 %val32_trunc, i32* %addr32_trunc 183*9880d681SAndroid Build Coastguard Worker; CHECK: ldur {{x[0-9]+}}, [{{x[0-9]+}}, #255] 184*9880d681SAndroid Build Coastguard Worker; CHECK: stur {{w[0-9]+}}, [{{x[0-9]+}}, #-20] 185*9880d681SAndroid Build Coastguard Worker 186*9880d681SAndroid Build Coastguard Worker ret void 187*9880d681SAndroid Build Coastguard Worker} 188*9880d681SAndroid Build Coastguard Worker 189*9880d681SAndroid Build Coastguard Workerdefine void @ldst_float() { 190*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: ldst_float: 191*9880d681SAndroid Build Coastguard Worker 192*9880d681SAndroid Build Coastguard Worker %addr_8bit = load i8*, i8** @varptr 193*9880d681SAndroid Build Coastguard Worker %addrfp_8 = getelementptr i8, i8* %addr_8bit, i64 -5 194*9880d681SAndroid Build Coastguard Worker %addrfp = bitcast i8* %addrfp_8 to float* 195*9880d681SAndroid Build Coastguard Worker 196*9880d681SAndroid Build Coastguard Worker %valfp = load volatile float, float* %addrfp 197*9880d681SAndroid Build Coastguard Worker; CHECK: ldur {{s[0-9]+}}, [{{x[0-9]+}}, #-5] 198*9880d681SAndroid Build Coastguard Worker; CHECK-NOFP-NOT: ldur {{s[0-9]+}}, 199*9880d681SAndroid Build Coastguard Worker 200*9880d681SAndroid Build Coastguard Worker store volatile float %valfp, float* %addrfp 201*9880d681SAndroid Build Coastguard Worker; CHECK: stur {{s[0-9]+}}, [{{x[0-9]+}}, #-5] 202*9880d681SAndroid Build Coastguard Worker; CHECK-NOFP-NOT: stur {{s[0-9]+}}, 203*9880d681SAndroid Build Coastguard Worker 204*9880d681SAndroid Build Coastguard Worker ret void 205*9880d681SAndroid Build Coastguard Worker} 206*9880d681SAndroid Build Coastguard Worker 207*9880d681SAndroid Build Coastguard Workerdefine void @ldst_double() { 208*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: ldst_double: 209*9880d681SAndroid Build Coastguard Worker 210*9880d681SAndroid Build Coastguard Worker %addr_8bit = load i8*, i8** @varptr 211*9880d681SAndroid Build Coastguard Worker %addrfp_8 = getelementptr i8, i8* %addr_8bit, i64 4 212*9880d681SAndroid Build Coastguard Worker %addrfp = bitcast i8* %addrfp_8 to double* 213*9880d681SAndroid Build Coastguard Worker 214*9880d681SAndroid Build Coastguard Worker %valfp = load volatile double, double* %addrfp 215*9880d681SAndroid Build Coastguard Worker; CHECK: ldur {{d[0-9]+}}, [{{x[0-9]+}}, #4] 216*9880d681SAndroid Build Coastguard Worker; CHECK-NOFP-NOT: ldur {{d[0-9]+}}, 217*9880d681SAndroid Build Coastguard Worker 218*9880d681SAndroid Build Coastguard Worker store volatile double %valfp, double* %addrfp 219*9880d681SAndroid Build Coastguard Worker; CHECK: stur {{d[0-9]+}}, [{{x[0-9]+}}, #4] 220*9880d681SAndroid Build Coastguard Worker; CHECK-NOFP-NOT: stur {{d[0-9]+}}, 221*9880d681SAndroid Build Coastguard Worker 222*9880d681SAndroid Build Coastguard Worker ret void 223*9880d681SAndroid Build Coastguard Worker} 224