1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc --mtriple=loongarch32 -mattr=+d --verify-machineinstrs < %s | FileCheck %s --check-prefix=LA32 3; RUN: llc --mtriple=loongarch64 -mattr=+d --verify-machineinstrs < %s | FileCheck %s --check-prefix=LA64 4 5define i32 @m_offset_neg_2049(ptr %p) nounwind { 6; LA32-LABEL: m_offset_neg_2049: 7; LA32: # %bb.0: 8; LA32-NEXT: addi.w $a0, $a0, -2048 9; LA32-NEXT: addi.w $a0, $a0, -1 10; LA32-NEXT: #APP 11; LA32-NEXT: ld.w $a0, $a0, 0 12; LA32-NEXT: #NO_APP 13; LA32-NEXT: ret 14; 15; LA64-LABEL: m_offset_neg_2049: 16; LA64: # %bb.0: 17; LA64-NEXT: addi.d $a0, $a0, -2048 18; LA64-NEXT: addi.d $a0, $a0, -1 19; LA64-NEXT: #APP 20; LA64-NEXT: ld.w $a0, $a0, 0 21; LA64-NEXT: #NO_APP 22; LA64-NEXT: ret 23 %1 = getelementptr inbounds i8, ptr %p, i32 -2049 24 %2 = call i32 asm "ld.w $0, $1", "=r,*m"(ptr elementtype(i32) %1) 25 ret i32 %2 26} 27 28define i32 @m_offset_neg_2048(ptr %p) nounwind { 29; LA32-LABEL: m_offset_neg_2048: 30; LA32: # %bb.0: 31; LA32-NEXT: #APP 32; LA32-NEXT: ld.w $a0, $a0, -2048 33; LA32-NEXT: #NO_APP 34; LA32-NEXT: ret 35; 36; LA64-LABEL: m_offset_neg_2048: 37; LA64: # %bb.0: 38; LA64-NEXT: #APP 39; LA64-NEXT: ld.w $a0, $a0, -2048 40; LA64-NEXT: #NO_APP 41; LA64-NEXT: ret 42 %1 = getelementptr inbounds i8, ptr %p, i32 -2048 43 %2 = call i32 asm "ld.w $0, $1", "=r,*m"(ptr elementtype(i32) %1) 44 ret i32 %2 45} 46 47define i32 @m_offset_neg_1(ptr %p) nounwind { 48; LA32-LABEL: m_offset_neg_1: 49; LA32: # %bb.0: 50; LA32-NEXT: #APP 51; LA32-NEXT: ld.w $a0, $a0, -1 52; LA32-NEXT: #NO_APP 53; LA32-NEXT: ret 54; 55; LA64-LABEL: m_offset_neg_1: 56; LA64: # %bb.0: 57; LA64-NEXT: #APP 58; LA64-NEXT: ld.w $a0, $a0, -1 59; LA64-NEXT: #NO_APP 60; LA64-NEXT: ret 61 %1 = getelementptr inbounds i8, ptr %p, i32 -1 62 %2 = call i32 asm "ld.w $0, $1", "=r,*m"(ptr elementtype(i32) %1) 63 ret i32 %2 64} 65 66define i32 @m_offset_0(ptr %p) nounwind { 67; LA32-LABEL: m_offset_0: 68; LA32: # %bb.0: 69; LA32-NEXT: #APP 70; LA32-NEXT: ld.w $a0, $a0, 0 71; LA32-NEXT: #NO_APP 72; LA32-NEXT: ret 73; 74; LA64-LABEL: m_offset_0: 75; LA64: # %bb.0: 76; LA64-NEXT: #APP 77; LA64-NEXT: ld.w $a0, $a0, 0 78; LA64-NEXT: #NO_APP 79; LA64-NEXT: ret 80 %1 = call i32 asm "ld.w $0, $1", "=r,*m"(ptr elementtype(i32) %p) 81 ret i32 %1 82} 83 84define i32 @m_offset_1(ptr %p) nounwind { 85; LA32-LABEL: m_offset_1: 86; LA32: # %bb.0: 87; LA32-NEXT: #APP 88; LA32-NEXT: ld.w $a0, $a0, 1 89; LA32-NEXT: #NO_APP 90; LA32-NEXT: ret 91; 92; LA64-LABEL: m_offset_1: 93; LA64: # %bb.0: 94; LA64-NEXT: #APP 95; LA64-NEXT: ld.w $a0, $a0, 1 96; LA64-NEXT: #NO_APP 97; LA64-NEXT: ret 98 %1 = getelementptr inbounds i8, ptr %p, i32 1 99 %2 = call i32 asm "ld.w $0, $1", "=r,*m"(ptr elementtype(i32) %1) 100 ret i32 %2 101} 102 103define i32 @m_offset_2047(ptr %p) nounwind { 104; LA32-LABEL: m_offset_2047: 105; LA32: # %bb.0: 106; LA32-NEXT: #APP 107; LA32-NEXT: ld.w $a0, $a0, 2047 108; LA32-NEXT: #NO_APP 109; LA32-NEXT: ret 110; 111; LA64-LABEL: m_offset_2047: 112; LA64: # %bb.0: 113; LA64-NEXT: #APP 114; LA64-NEXT: ld.w $a0, $a0, 2047 115; LA64-NEXT: #NO_APP 116; LA64-NEXT: ret 117 %1 = getelementptr inbounds i8, ptr %p, i32 2047 118 %2 = call i32 asm "ld.w $0, $1", "=r,*m"(ptr elementtype(i32) %1) 119 ret i32 %2 120} 121 122define i32 @m_offset_2048(ptr %p) nounwind { 123; LA32-LABEL: m_offset_2048: 124; LA32: # %bb.0: 125; LA32-NEXT: addi.w $a0, $a0, 2047 126; LA32-NEXT: addi.w $a0, $a0, 1 127; LA32-NEXT: #APP 128; LA32-NEXT: ld.w $a0, $a0, 0 129; LA32-NEXT: #NO_APP 130; LA32-NEXT: ret 131; 132; LA64-LABEL: m_offset_2048: 133; LA64: # %bb.0: 134; LA64-NEXT: addi.d $a0, $a0, 2047 135; LA64-NEXT: addi.d $a0, $a0, 1 136; LA64-NEXT: #APP 137; LA64-NEXT: ld.w $a0, $a0, 0 138; LA64-NEXT: #NO_APP 139; LA64-NEXT: ret 140 %1 = getelementptr inbounds i8, ptr %p, i32 2048 141 %2 = call i32 asm "ld.w $0, $1", "=r,*m"(ptr elementtype(i32) %1) 142 ret i32 %2 143} 144 145@g_i32 = dso_local global i32 0 146 147define i32 @m_addr_pcrel() nounwind { 148; LA32-LABEL: m_addr_pcrel: 149; LA32: # %bb.0: 150; LA32-NEXT: pcalau12i $a1, %pc_hi20(g_i32) 151; LA32-NEXT: #APP 152; LA32-NEXT: ld.w $a0, $a1, %pc_lo12(g_i32) 153; LA32-NEXT: #NO_APP 154; LA32-NEXT: ret 155; 156; LA64-LABEL: m_addr_pcrel: 157; LA64: # %bb.0: 158; LA64-NEXT: pcalau12i $a1, %pc_hi20(g_i32) 159; LA64-NEXT: #APP 160; LA64-NEXT: ld.w $a0, $a1, %pc_lo12(g_i32) 161; LA64-NEXT: #NO_APP 162; LA64-NEXT: ret 163 %1 = tail call i32 asm sideeffect "ld.w $0, $1", "=&r,*m"(ptr nonnull elementtype(i32) @g_i32) 164 ret i32 %1 165} 166 167define i32 @m_addr_should_not_fold() nounwind { 168; LA32-LABEL: m_addr_should_not_fold: 169; LA32: # %bb.0: 170; LA32-NEXT: pcalau12i $a0, %pc_hi20(g_i32) 171; LA32-NEXT: addi.w $a1, $a0, %pc_lo12(g_i32) 172; LA32-NEXT: #APP 173; LA32-NEXT: ld.w $a0, $a1, 0 174; LA32-NEXT: #NO_APP 175; LA32-NEXT: ret 176; 177; LA64-LABEL: m_addr_should_not_fold: 178; LA64: # %bb.0: 179; LA64-NEXT: pcalau12i $a0, %pc_hi20(g_i32) 180; LA64-NEXT: addi.d $a1, $a0, %pc_lo12(g_i32) 181; LA64-NEXT: #APP 182; LA64-NEXT: ld.w $a0, $a1, 0 183; LA64-NEXT: #NO_APP 184; LA64-NEXT: ret 185 %1 = tail call i32 asm sideeffect "ld.w $0, $1, 0", "=&r,r,~{memory}"(ptr nonnull @g_i32) 186 ret i32 %1 187} 188