683 lines · plain
1; RUN: llc -o - %s -mtriple=arm64-apple-ios -O2 | FileCheck %s2; RUN: llc -o - %s -mtriple=arm64_32-apple-watchos -O2 | FileCheck %s3; RUN: llc -o - %s -mtriple=arm64-linux-gnu -O2 | FileCheck %s --check-prefix=CHECK-ELF4 5; CHECK-ELF-NOT: .loh6; CHECK-ELF-NOT: AdrpAdrp7; CHECK-ELF-NOT: AdrpAdd8; CHECK-ELF-NOT: AdrpLdrGot9 10@a = internal unnamed_addr global i32 0, align 411@b = external global i3212 13; Function Attrs: noinline nounwind ssp14define void @foo(i32 %t) {15entry:16 %tmp = load i32, ptr @a, align 417 %add = add nsw i32 %tmp, %t18 store i32 %add, ptr @a, align 419 ret void20}21 22; Function Attrs: nounwind ssp23; Testcase for <rdar://problem/15438605>, AdrpAdrp reuse is valid only when the first adrp24; dominates the second.25; The first adrp comes from the loading of 'a' and the second the loading of 'b'.26; 'a' is loaded in if.then, 'b' in if.end4, if.then does not dominates if.end4.27; CHECK-LABEL: _test28; CHECK: ret29; CHECK-NOT: .loh AdrpAdrp30define i32 @test(i32 %t) {31entry:32 %cmp = icmp sgt i32 %t, 533 br i1 %cmp, label %if.then, label %if.end434 35if.then: ; preds = %entry36 %tmp = load i32, ptr @a, align 437 %add = add nsw i32 %tmp, %t38 %cmp1 = icmp sgt i32 %add, 1239 br i1 %cmp1, label %if.then2, label %if.end440 41if.then2: ; preds = %if.then42 tail call void @foo(i32 %add)43 %tmp1 = load i32, ptr @a, align 444 br label %if.end445 46if.end4: ; preds = %if.then2, %if.then, %entry47 %t.addr.0 = phi i32 [ %tmp1, %if.then2 ], [ %t, %if.then ], [ %t, %entry ]48 %tmp2 = load i32, ptr @b, align 449 %add5 = add nsw i32 %tmp2, %t.addr.050 tail call void @foo(i32 %add5)51 %tmp3 = load i32, ptr @b, align 452 %add6 = add nsw i32 %tmp3, %t.addr.053 ret i32 %add654}55 56@C = common global i32 0, align 457 58; Check that we catch AdrpLdrGotLdr case when we have a simple chain:59; adrp -> ldrgot -> ldr.60; CHECK-LABEL: _getC61; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:62; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _C@GOTPAGE63; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:64; CHECK-NEXT: ldr {{[xw]}}[[LDRGOT_REG:[0-9]+]], [[[ADRP_REG]], _C@GOTPAGEOFF]65; CHECK-NEXT: [[LDR_LABEL:Lloh[0-9]+]]:66; CHECK-NEXT: ldr w0, [x[[LDRGOT_REG]]]67; CHECK-NEXT: ret68; CHECK: .loh AdrpLdrGotLdr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[LDR_LABEL]]69define i32 @getC() {70 %res = load i32, ptr @C, align 471 ret i32 %res72}73 74; LDRSW supports loading from a literal.75; Make sure we emit AdrpLdrGotLdr for those.76; CHECK-LABEL: _getSExtC77; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:78; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _C@GOTPAGE79; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:80; CHECK-NEXT: ldr {{[xw]}}[[LDRGOT_REG:[0-9]+]], [[[ADRP_REG]], _C@GOTPAGEOFF]81; CHECK-NEXT: [[LDR_LABEL:Lloh[0-9]+]]:82; CHECK-NEXT: ldrsw x0, [x[[LDRGOT_REG]]]83; CHECK-NEXT: ret84; CHECK: .loh AdrpLdrGotLdr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[LDR_LABEL]]85define i64 @getSExtC() {86 %res = load i32, ptr @C, align 487 %sextres = sext i32 %res to i6488 ret i64 %sextres89}90 91; It may not be safe to fold the literal in the load if the address is92; used several times.93; Make sure we emit AdrpLdrGot for those.94; CHECK-LABEL: _getSeveralC95; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:96; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _C@GOTPAGE97; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:98; CHECK-NEXT: ldr {{[xw]}}[[LDRGOT_REG:[0-9]+]], [[[ADRP_REG]], _C@GOTPAGEOFF]99; CHECK-NEXT: ldr [[LOAD:w[0-9]+]], [x[[LDRGOT_REG]]]100; CHECK-NEXT: add [[ADD:w[0-9]+]], [[LOAD]], w0101; CHECK-NEXT: str [[ADD]], [x[[LDRGOT_REG]]]102; CHECK-NEXT: ret103; CHECK: .loh AdrpLdrGot [[ADRP_LABEL]], [[LDRGOT_LABEL]]104define void @getSeveralC(i32 %t) {105entry:106 %tmp = load i32, ptr @C, align 4107 %add = add nsw i32 %tmp, %t108 store i32 %add, ptr @C, align 4109 ret void110}111 112; Make sure we catch that:113; adrp -> ldrgot -> str.114; CHECK-LABEL: _setC115; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:116; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _C@GOTPAGE117; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:118; CHECK-NEXT: ldr {{[xw]}}[[LDRGOT_REG:[0-9]+]], [[[ADRP_REG]], _C@GOTPAGEOFF]119; CHECK-NEXT: [[LDR_LABEL:Lloh[0-9]+]]:120; CHECK-NEXT: str w0, [x[[LDRGOT_REG]]]121; CHECK-NEXT: ret122; CHECK: .loh AdrpLdrGotStr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[LDR_LABEL]]123define void @setC(i32 %t) {124entry:125 store i32 %t, ptr @C, align 4126 ret void127}128 129; Perform the same tests for internal global and a displacement130; in the addressing mode.131; Indeed we will get an ADD for those instead of LOADGot.132@InternalC = internal global i32 0, align 4133 134; Check that we catch AdrpAddLdr case when we have a simple chain:135; adrp -> add -> ldr.136; CHECK-LABEL: _getInternalCPlus4137; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:138; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _InternalC@PAGE139; CHECK-NEXT: [[ADDGOT_LABEL:Lloh[0-9]+]]:140; CHECK-NEXT: add [[ADDGOT_REG:x[0-9]+]], [[ADRP_REG]], _InternalC@PAGEOFF141; CHECK-NEXT: [[LDR_LABEL:Lloh[0-9]+]]:142; CHECK-NEXT: ldr w0, [[[ADDGOT_REG]], #16]143; CHECK-NEXT: ret144; CHECK: .loh AdrpAddLdr [[ADRP_LABEL]], [[ADDGOT_LABEL]], [[LDR_LABEL]]145define i32 @getInternalCPlus4() {146 %addr = getelementptr inbounds i32, ptr @InternalC, i32 4147 %res = load i32, ptr %addr, align 4148 ret i32 %res149}150 151; LDRSW supports loading from a literal.152; Make sure we emit AdrpLdrGotLdr for those.153; CHECK-LABEL: _getSExtInternalCPlus4154; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:155; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _InternalC@PAGE156; CHECK-NEXT: [[ADDGOT_LABEL:Lloh[0-9]+]]:157; CHECK-NEXT: add [[ADDGOT_REG:x[0-9]+]], [[ADRP_REG]], _InternalC@PAGEOFF158; CHECK-NEXT: [[LDR_LABEL:Lloh[0-9]+]]:159; CHECK-NEXT: ldrsw x0, [[[ADDGOT_REG]], #16]160; CHECK-NEXT: ret161; CHECK: .loh AdrpAddLdr [[ADRP_LABEL]], [[ADDGOT_LABEL]], [[LDR_LABEL]]162define i64 @getSExtInternalCPlus4() {163 %addr = getelementptr inbounds i32, ptr @InternalC, i32 4164 %res = load i32, ptr %addr, align 4165 %sextres = sext i32 %res to i64166 ret i64 %sextres167}168 169; It may not be safe to fold the literal in the load if the address is170; used several times.171; Make sure we emit AdrpAdd for those.172; CHECK-LABEL: _getSeveralInternalCPlus4173; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:174; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _InternalC@PAGE175; CHECK-NEXT: [[ADDGOT_LABEL:Lloh[0-9]+]]:176; CHECK-NEXT: add [[ADDGOT_REG:x[0-9]+]], [[ADRP_REG]], _InternalC@PAGEOFF177; CHECK-NEXT: ldr [[LOAD:w[0-9]+]], [[[ADDGOT_REG]], #16]178; CHECK-NEXT: add [[ADD:w[0-9]+]], [[LOAD]], w0179; CHECK-NEXT: str [[ADD]], [[[ADDGOT_REG]], #16]180; CHECK-NEXT: ret181; CHECK: .loh AdrpAdd [[ADRP_LABEL]], [[ADDGOT_LABEL]]182define void @getSeveralInternalCPlus4(i32 %t) {183entry:184 %addr = getelementptr inbounds i32, ptr @InternalC, i32 4185 %tmp = load i32, ptr %addr, align 4186 %add = add nsw i32 %tmp, %t187 store i32 %add, ptr %addr, align 4188 ret void189}190 191; Make sure we catch that:192; adrp -> add -> str.193; CHECK-LABEL: _setInternalCPlus4194; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:195; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _InternalC@PAGE196; CHECK-NEXT: [[ADDGOT_LABEL:Lloh[0-9]+]]:197; CHECK-NEXT: add [[ADDGOT_REG:x[0-9]+]], [[ADRP_REG]], _InternalC@PAGEOFF198; CHECK-NEXT: [[LDR_LABEL:Lloh[0-9]+]]:199; CHECK-NEXT: str w0, [[[ADDGOT_REG]], #16]200; CHECK-NEXT: ret201; CHECK: .loh AdrpAddStr [[ADRP_LABEL]], [[ADDGOT_LABEL]], [[LDR_LABEL]]202define void @setInternalCPlus4(i32 %t) {203entry:204 %addr = getelementptr inbounds i32, ptr @InternalC, i32 4205 store i32 %t, ptr %addr, align 4206 ret void207}208 209; Check that we catch AdrpAddLdr case when we have a simple chain:210; adrp -> ldr.211; CHECK-LABEL: _getInternalC212; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:213; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _InternalC@PAGE214; CHECK-NEXT: [[LDR_LABEL:Lloh[0-9]+]]:215; CHECK-NEXT: ldr w0, [[[ADRP_REG]], _InternalC@PAGEOFF]216; CHECK-NEXT: ret217; CHECK: .loh AdrpLdr [[ADRP_LABEL]], [[LDR_LABEL]]218define i32 @getInternalC() {219 %res = load i32, ptr @InternalC, align 4220 ret i32 %res221}222 223; LDRSW supports loading from a literal.224; Make sure we emit AdrpLdrGotLdr for those.225; CHECK-LABEL: _getSExtInternalC226; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:227; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _InternalC@PAGE228; CHECK-NEXT: [[LDR_LABEL:Lloh[0-9]+]]:229; CHECK-NEXT: ldrsw x0, [[[ADRP_REG]], _InternalC@PAGEOFF]230; CHECK-NEXT: ret231; CHECK: .loh AdrpLdr [[ADRP_LABEL]], [[LDR_LABEL]]232define i64 @getSExtInternalC() {233 %res = load i32, ptr @InternalC, align 4234 %sextres = sext i32 %res to i64235 ret i64 %sextres236}237 238; It may not be safe to fold the literal in the load if the address is239; used several times.240; Make sure we do not catch anything here. We have a adrp alone,241; there is not much we can do about it.242; CHECK-LABEL: _getSeveralInternalC243; CHECK: adrp [[ADRP_REG:x[0-9]+]], _InternalC@PAGE244; CHECK-NEXT: ldr [[LOAD:w[0-9]+]], [[[ADRP_REG]], _InternalC@PAGEOFF]245; CHECK-NEXT: add [[ADD:w[0-9]+]], [[LOAD]], w0246; CHECK-NEXT: str [[ADD]], [[[ADRP_REG]], _InternalC@PAGEOFF]247; CHECK-NEXT: ret248define void @getSeveralInternalC(i32 %t) {249entry:250 %tmp = load i32, ptr @InternalC, align 4251 %add = add nsw i32 %tmp, %t252 store i32 %add, ptr @InternalC, align 4253 ret void254}255 256; Make sure we do not catch anything when:257; adrp -> str.258; We cannot fold anything in the str at this point.259; Indeed, strs do not support litterals.260; CHECK-LABEL: _setInternalC261; CHECK: adrp [[ADRP_REG:x[0-9]+]], _InternalC@PAGE262; CHECK-NEXT: str w0, [[[ADRP_REG]], _InternalC@PAGEOFF]263; CHECK-NEXT: ret264define void @setInternalC(i32 %t) {265entry:266 store i32 %t, ptr @InternalC, align 4267 ret void268}269 270; Now check other variant of loads/stores.271 272@D = common global i8 0, align 4273 274; LDRB does not support loading from a literal.275; Make sure we emit AdrpLdrGot and not AdrpLdrGotLdr for those.276; CHECK-LABEL: _getD277; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:278; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _D@GOTPAGE279; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:280; CHECK-NEXT: ldr {{[xw]}}[[LDRGOT_REG:[0-9]+]], [[[ADRP_REG]], _D@GOTPAGEOFF]281; CHECK-NEXT: ldrb w0, [x[[LDRGOT_REG]]]282; CHECK-NEXT: ret283; CHECK: .loh AdrpLdrGot [[ADRP_LABEL]], [[LDRGOT_LABEL]]284define i8 @getD() {285 %res = load i8, ptr @D, align 4286 ret i8 %res287}288 289; CHECK-LABEL: _setD290; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:291; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _D@GOTPAGE292; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:293; CHECK-NEXT: ldr {{[xw]}}[[LDRGOT_REG:[0-9]+]], [[[ADRP_REG]], _D@GOTPAGEOFF]294; CHECK-NEXT: [[STR_LABEL:Lloh[0-9]+]]:295; CHECK-NEXT: strb w0, [x[[LDRGOT_REG]]]296; CHECK-NEXT: ret297; CHECK: .loh AdrpLdrGotStr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[STR_LABEL]]298define void @setD(i8 %t) {299 store i8 %t, ptr @D, align 4300 ret void301}302 303; LDRSB supports loading from a literal.304; Make sure we emit AdrpLdrGotLdr for those.305; CHECK-LABEL: _getSExtD306; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:307; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _D@GOTPAGE308; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:309; CHECK-NEXT: ldr {{[xw]}}[[LDRGOT_REG:[0-9]+]], [[[ADRP_REG]], _D@GOTPAGEOFF]310; CHECK-NEXT: [[LDR_LABEL:Lloh[0-9]+]]:311; CHECK-NEXT: ldrsb w0, [x[[LDRGOT_REG]]]312; CHECK-NEXT: ret313; CHECK: .loh AdrpLdrGotLdr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[LDR_LABEL]]314define i32 @getSExtD() {315 %res = load i8, ptr @D, align 4316 %sextres = sext i8 %res to i32317 ret i32 %sextres318}319 320; LDRSB supports loading from a literal.321; Make sure we emit AdrpLdrGotLdr for those.322; CHECK-LABEL: _getSExt64D323; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:324; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _D@GOTPAGE325; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:326; CHECK-NEXT: ldr {{[xw]}}[[LDRGOT_REG:[0-9]+]], [[[ADRP_REG]], _D@GOTPAGEOFF]327; CHECK-NEXT: [[LDR_LABEL:Lloh[0-9]+]]:328; CHECK-NEXT: ldrsb x0, [x[[LDRGOT_REG]]]329; CHECK-NEXT: ret330; CHECK: .loh AdrpLdrGotLdr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[LDR_LABEL]]331define i64 @getSExt64D() {332 %res = load i8, ptr @D, align 4333 %sextres = sext i8 %res to i64334 ret i64 %sextres335}336 337@E = common global i16 0, align 4338 339; LDRH does not support loading from a literal.340; Make sure we emit AdrpLdrGot and not AdrpLdrGotLdr for those.341; CHECK-LABEL: _getE342; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:343; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _E@GOTPAGE344; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:345; CHECK-NEXT: ldr {{[xw]}}[[LDRGOT_REG:[0-9]+]], [[[ADRP_REG]], _E@GOTPAGEOFF]346; CHECK-NEXT: ldrh w0, [x[[LDRGOT_REG]]]347; CHECK-NEXT: ret348; CHECK: .loh AdrpLdrGot [[ADRP_LABEL]], [[LDRGOT_LABEL]]349define i16 @getE() {350 %res = load i16, ptr @E, align 4351 ret i16 %res352}353 354; LDRSH supports loading from a literal.355; Make sure we emit AdrpLdrGotLdr for those.356; CHECK-LABEL: _getSExtE357; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:358; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _E@GOTPAGE359; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:360; CHECK-NEXT: ldr {{[xw]}}[[LDRGOT_REG:[0-9]+]], [[[ADRP_REG]], _E@GOTPAGEOFF]361; CHECK-NEXT: [[LDR_LABEL:Lloh[0-9]+]]:362; CHECK-NEXT: ldrsh w0, [x[[LDRGOT_REG]]]363; CHECK-NEXT: ret364; CHECK: .loh AdrpLdrGotLdr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[LDR_LABEL]]365define i32 @getSExtE() {366 %res = load i16, ptr @E, align 4367 %sextres = sext i16 %res to i32368 ret i32 %sextres369}370 371; CHECK-LABEL: _setE372; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:373; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _E@GOTPAGE374; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:375; CHECK-NEXT: ldr {{[xw]}}[[LDRGOT_REG:[0-9]+]], [[[ADRP_REG]], _E@GOTPAGEOFF]376; CHECK-NEXT: [[STR_LABEL:Lloh[0-9]+]]:377; CHECK-NEXT: strh w0, [x[[LDRGOT_REG]]]378; CHECK-NEXT: ret379; CHECK: .loh AdrpLdrGotStr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[STR_LABEL]]380define void @setE(i16 %t) {381 store i16 %t, ptr @E, align 4382 ret void383}384 385; LDRSH supports loading from a literal.386; Make sure we emit AdrpLdrGotLdr for those.387; CHECK-LABEL: _getSExt64E388; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:389; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _E@GOTPAGE390; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:391; CHECK-NEXT: ldr {{[xw]}}[[LDRGOT_REG:[0-9]+]], [[[ADRP_REG]], _E@GOTPAGEOFF]392; CHECK-NEXT: [[LDR_LABEL:Lloh[0-9]+]]:393; CHECK-NEXT: ldrsh x0, [x[[LDRGOT_REG]]]394; CHECK-NEXT: ret395; CHECK: .loh AdrpLdrGotLdr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[LDR_LABEL]]396define i64 @getSExt64E() {397 %res = load i16, ptr @E, align 4398 %sextres = sext i16 %res to i64399 ret i64 %sextres400}401 402@F = common global i64 0, align 4403 404; LDR supports loading from a literal.405; Make sure we emit AdrpLdrGotLdr for those.406; CHECK-LABEL: _getF407; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:408; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _F@GOTPAGE409; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:410; CHECK-NEXT: ldr {{[xw]}}[[LDRGOT_REG:[0-9]+]], [[[ADRP_REG]], _F@GOTPAGEOFF]411; CHECK-NEXT: [[LDR_LABEL:Lloh[0-9]+]]:412; CHECK-NEXT: ldr x0, [x[[LDRGOT_REG]]]413; CHECK-NEXT: ret414; CHECK: .loh AdrpLdrGotLdr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[LDR_LABEL]]415define i64 @getF() {416 %res = load i64, ptr @F, align 4417 ret i64 %res418}419 420; CHECK-LABEL: _setF421; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:422; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _F@GOTPAGE423; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:424; CHECK-NEXT: ldr {{[xw]}}[[LDRGOT_REG:[0-9]+]], [[[ADRP_REG]], _F@GOTPAGEOFF]425; CHECK-NEXT: [[STR_LABEL:Lloh[0-9]+]]:426; CHECK-NEXT: str x0, [x[[LDRGOT_REG]]]427; CHECK-NEXT: ret428; CHECK: .loh AdrpLdrGotStr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[STR_LABEL]]429define void @setF(i64 %t) {430 store i64 %t, ptr @F, align 4431 ret void432}433 434@G = common global float 0.0, align 4435 436; LDR float supports loading from a literal.437; Make sure we emit AdrpLdrGotLdr for those.438; CHECK-LABEL: _getG439; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:440; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _G@GOTPAGE441; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:442; CHECK-NEXT: ldr {{[xw]}}[[LDRGOT_REG:[0-9]+]], [[[ADRP_REG]], _G@GOTPAGEOFF]443; CHECK-NEXT: [[LDR_LABEL:Lloh[0-9]+]]:444; CHECK-NEXT: ldr s0, [x[[LDRGOT_REG]]]445; CHECK-NEXT: ret446; CHECK: .loh AdrpLdrGotLdr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[LDR_LABEL]]447define float @getG() {448 %res = load float, ptr @G, align 4449 ret float %res450}451 452; CHECK-LABEL: _setG453; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:454; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _G@GOTPAGE455; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:456; CHECK-NEXT: ldr {{[xw]}}[[LDRGOT_REG:[0-9]+]], [[[ADRP_REG]], _G@GOTPAGEOFF]457; CHECK-NEXT: [[STR_LABEL:Lloh[0-9]+]]:458; CHECK-NEXT: str s0, [x[[LDRGOT_REG]]]459; CHECK-NEXT: ret460; CHECK: .loh AdrpLdrGotStr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[STR_LABEL]]461define void @setG(float %t) {462 store float %t, ptr @G, align 4463 ret void464}465 466@H = common global half 0.0, align 4467 468; LDR half supports loading from a literal.469; Make sure we emit AdrpLdrGotLdr for those.470; CHECK-LABEL: _getH471; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:472; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _H@GOTPAGE473; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:474; CHECK-NEXT: ldr {{[xw]}}[[LDRGOT_REG:[0-9]+]], [[[ADRP_REG]], _H@GOTPAGEOFF]475; CHECK-NEXT: [[LDR_LABEL:Lloh[0-9]+]]:476; CHECK-NEXT: ldr h0, [x[[LDRGOT_REG]]]477; CHECK-NEXT: ret478; CHECK: .loh AdrpLdrGotLdr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[LDR_LABEL]]479define half @getH() {480 %res = load half, ptr @H, align 4481 ret half %res482}483 484; CHECK-LABEL: _setH485; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:486; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _H@GOTPAGE487; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:488; CHECK-NEXT: ldr {{[xw]}}[[LDRGOT_REG:[0-9]+]], [[[ADRP_REG]], _H@GOTPAGEOFF]489; CHECK-NEXT: [[STR_LABEL:Lloh[0-9]+]]:490; CHECK-NEXT: str h0, [x[[LDRGOT_REG]]]491; CHECK-NEXT: ret492; CHECK: .loh AdrpLdrGotStr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[STR_LABEL]]493define void @setH(half %t) {494 store half %t, ptr @H, align 4495 ret void496}497 498@I = common global double 0.0, align 4499 500; LDR double supports loading from a literal.501; Make sure we emit AdrpLdrGotLdr for those.502; CHECK-LABEL: _getI503; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:504; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _I@GOTPAGE505; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:506; CHECK-NEXT: ldr {{[xw]}}[[LDRGOT_REG:[0-9]+]], [[[ADRP_REG]], _I@GOTPAGEOFF]507; CHECK-NEXT: [[LDR_LABEL:Lloh[0-9]+]]:508; CHECK-NEXT: ldr d0, [x[[LDRGOT_REG]]]509; CHECK-NEXT: ret510; CHECK: .loh AdrpLdrGotLdr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[LDR_LABEL]]511define double @getI() {512 %res = load double, ptr @I, align 4513 ret double %res514}515 516; CHECK-LABEL: _setI517; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:518; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _I@GOTPAGE519; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:520; CHECK-NEXT: ldr {{[xw]}}[[LDRGOT_REG:[0-9]+]], [[[ADRP_REG]], _I@GOTPAGEOFF]521; CHECK-NEXT: [[STR_LABEL:Lloh[0-9]+]]:522; CHECK-NEXT: str d0, [x[[LDRGOT_REG]]]523; CHECK-NEXT: ret524; CHECK: .loh AdrpLdrGotStr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[STR_LABEL]]525define void @setI(double %t) {526 store double %t, ptr @I, align 4527 ret void528}529 530@J = common global <2 x i32> <i32 0, i32 0>, align 4531 532; LDR 64-bit vector supports loading from a literal.533; Make sure we emit AdrpLdrGotLdr for those.534; CHECK-LABEL: _getJ535; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:536; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _J@GOTPAGE537; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:538; CHECK-NEXT: ldr {{[xw]}}[[LDRGOT_REG:[0-9]+]], [[[ADRP_REG]], _J@GOTPAGEOFF]539; CHECK-NEXT: [[LDR_LABEL:Lloh[0-9]+]]:540; CHECK-NEXT: ldr d0, [x[[LDRGOT_REG]]]541; CHECK-NEXT: ret542; CHECK: .loh AdrpLdrGotLdr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[LDR_LABEL]]543define <2 x i32> @getJ() {544 %res = load <2 x i32>, ptr @J, align 4545 ret <2 x i32> %res546}547 548; CHECK-LABEL: _setJ549; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:550; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _J@GOTPAGE551; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:552; CHECK-NEXT: ldr {{[xw]}}[[LDRGOT_REG:[0-9]+]], [[[ADRP_REG]], _J@GOTPAGEOFF]553; CHECK-NEXT: [[STR_LABEL:Lloh[0-9]+]]:554; CHECK-NEXT: str d0, [x[[LDRGOT_REG]]]555; CHECK-NEXT: ret556; CHECK: .loh AdrpLdrGotStr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[STR_LABEL]]557define void @setJ(<2 x i32> %t) {558 store <2 x i32> %t, ptr @J, align 4559 ret void560}561 562@K = common global <4 x i32> <i32 0, i32 0, i32 0, i32 0>, align 4563 564; LDR 128-bit vector supports loading from a literal.565; Make sure we emit AdrpLdrGotLdr for those.566; CHECK-LABEL: _getK567; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:568; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _K@GOTPAGE569; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:570; CHECK-NEXT: ldr {{[xw]}}[[LDRGOT_REG:[0-9]+]], [[[ADRP_REG]], _K@GOTPAGEOFF]571; CHECK-NEXT: [[LDR_LABEL:Lloh[0-9]+]]:572; CHECK-NEXT: ldr q0, [x[[LDRGOT_REG]]]573; CHECK-NEXT: ret574; CHECK: .loh AdrpLdrGotLdr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[LDR_LABEL]]575define <4 x i32> @getK() {576 %res = load <4 x i32>, ptr @K, align 4577 ret <4 x i32> %res578}579 580; CHECK-LABEL: _setK581; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:582; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _K@GOTPAGE583; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:584; CHECK-NEXT: ldr {{[xw]}}[[LDRGOT_REG:[0-9]+]], [[[ADRP_REG]], _K@GOTPAGEOFF]585; CHECK-NEXT: [[STR_LABEL:Lloh[0-9]+]]:586; CHECK-NEXT: str q0, [x[[LDRGOT_REG]]]587; CHECK-NEXT: ret588; CHECK: .loh AdrpLdrGotStr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[STR_LABEL]]589define void @setK(<4 x i32> %t) {590 store <4 x i32> %t, ptr @K, align 4591 ret void592}593 594@L = common global <1 x i8> <i8 0>, align 4595 596; LDR 8-bit vector supports loading from a literal.597; Make sure we emit AdrpLdrGotLdr for those.598; CHECK-LABEL: _getL599; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:600; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _L@GOTPAGE601; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:602; CHECK-NEXT: ldr {{[xw]}}[[LDRGOT_REG:[0-9]+]], [[[ADRP_REG]], _L@GOTPAGEOFF]603; CHECK-NEXT: [[LDR_LABEL:Lloh[0-9]+]]:604; CHECK-NEXT: ldr b0, [x[[LDRGOT_REG]]]605; CHECK-NEXT: ret606; CHECK: .loh AdrpLdrGotLdr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[LDR_LABEL]]607define <1 x i8> @getL() {608 %res = load <1 x i8>, ptr @L, align 4609 ret <1 x i8> %res610}611 612; CHECK-LABEL: _setL613; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:614; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _L@GOTPAGE615; CHECK-NEXT: ; kill616; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:617; CHECK-NEXT: ldr {{[xw]}}[[LDRGOT_REG:[0-9]+]], [[[ADRP_REG]], _L@GOTPAGEOFF]618; CHECK-NEXT: [[STR_LABEL:Lloh[0-9]+]]:619; CHECK-NEXT: str b0, [x[[LDRGOT_REG]]]620; CHECK-NEXT: ret621; CHECK: .loh AdrpLdrGotStr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[STR_LABEL]]622define void @setL(<1 x i8> %t) {623 store <1 x i8> %t, ptr @L, align 4624 ret void625}626 627; Make sure we do not assert when we do not track628; all the aliases of a tuple register.629; Indeed the tuple register can be tracked because of630; one of its element, but the other elements of the tuple631; do not need to be tracked and we used to assert on that.632; Note: The test case is fragile in the sense that we need633; a tuple register to appear in the lowering. Thus, the target634; cpu is required to have the problem reproduced.635; CHECK-LABEL: _uninterestingSub636; CHECK: [[LOH_LABEL0:Lloh[0-9]+]]:637; CHECK: adrp [[ADRP_REG:x[0-9]+]], [[CONSTPOOL:lCPI[0-9]+_[0-9]+]]@PAGE638; CHECK: [[LOH_LABEL1:Lloh[0-9]+]]:639; CHECK: ldr q[[IDX:[0-9]+]], [[[ADRP_REG]], [[CONSTPOOL]]@PAGEOFF]640; The tuple comes from the next instruction.641; CHECK: ext.16b v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}, #1642; CHECK: ret643; CHECK: .loh AdrpLdr [[LOH_LABEL0]], [[LOH_LABEL1]]644define void @uninterestingSub(ptr nocapture %row) #0 {645 %tmp = bitcast ptr %row to ptr646 %tmp1 = load <16 x i8>, ptr %tmp, align 16647 %vext43 = shufflevector <16 x i8> <i8 undef, i8 16, i8 15, i8 14, i8 13, i8 12, i8 11, i8 10, i8 9, i8 8, i8 7, i8 6, i8 5, i8 4, i8 3, i8 2>, <16 x i8> %tmp1, <16 x i32> <i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16>648 %add.i.414 = add <16 x i8> zeroinitializer, %vext43649 store <16 x i8> %add.i.414, ptr %tmp, align 16650 %add.ptr51 = getelementptr inbounds i8, ptr %row, i64 16651 %tmp2 = bitcast ptr %add.ptr51 to ptr652 %tmp3 = load <16 x i8>, ptr %tmp2, align 16653 %tmp4 = bitcast ptr undef to ptr654 %tmp5 = load <16 x i8>, ptr %tmp4, align 16655 %vext157 = shufflevector <16 x i8> %tmp3, <16 x i8> %tmp5, <16 x i32> <i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16>656 %add.i.402 = add <16 x i8> zeroinitializer, %vext157657 store <16 x i8> %add.i.402, ptr %tmp4, align 16658 ret void659}660 661@.str.89 = external unnamed_addr constant [12 x i8], align 1662@.str.90 = external unnamed_addr constant [5 x i8], align 1663; CHECK-LABEL: test_r274582664define void @test_r274582(double %x, i1 %arg) {665entry:666 br i1 %arg, label %if.then.i, label %if.end.i667if.then.i:668 ret void669if.end.i:670; CHECK: .loh AdrpLdrGot671; CHECK: .loh AdrpLdrGot672; CHECK: .loh AdrpAdrp673; CHECK: .loh AdrpLdr674 %mul = fmul double %x, 1.000000e-06675 %add = fadd double %mul, %mul676 %sub = fsub double %add, %add677 call void (ptr, ...) @callee(ptr @.str.89, ptr @.str.90, double %sub)678 unreachable679}680declare void @callee(ptr nocapture readonly, ...)681 682attributes #0 = { "target-cpu"="cyclone" }683