Skip to content

Commit 7d48a9e

Browse files
xen0nSixWeining
authored andcommitted
[LoongArch] Support register-register-addressed GPR loads/stores
Differential Revision: https://reviews.llvm.org/D131380
1 parent 9d1eeef commit 7d48a9e

File tree

2 files changed

+278
-0
lines changed

2 files changed

+278
-0
lines changed

llvm/lib/Target/LoongArch/LoongArchInstrInfo.td

+30
Original file line numberDiff line numberDiff line change
@@ -857,6 +857,24 @@ defm : LdPat<zextloadi32, LD_WU, i64>;
857857
defm : LdPat<load, LD_D, i64>;
858858
} // Predicates = [IsLA64]
859859

860+
// LA64 register-register-addressed loads
861+
let Predicates = [IsLA64] in {
862+
class RegRegLdPat<PatFrag LoadOp, LAInst Inst>
863+
: Pat<(i64 (LoadOp (add BaseAddr:$rj, GPR:$rk))),
864+
(Inst BaseAddr:$rj, GPR:$rk)>;
865+
866+
def : RegRegLdPat<extloadi8, LDX_B>;
867+
def : RegRegLdPat<sextloadi8, LDX_B>;
868+
def : RegRegLdPat<zextloadi8, LDX_BU>;
869+
def : RegRegLdPat<extloadi16, LDX_H>;
870+
def : RegRegLdPat<sextloadi16, LDX_H>;
871+
def : RegRegLdPat<zextloadi16, LDX_HU>;
872+
def : RegRegLdPat<extloadi32, LDX_W>;
873+
def : RegRegLdPat<sextloadi32, LDX_W>;
874+
def : RegRegLdPat<zextloadi32, LDX_WU>;
875+
def : RegRegLdPat<load, LDX_D>;
876+
} // Predicates = [IsLA64]
877+
860878
/// Stores
861879

862880
multiclass StPat<PatFrag StoreOp, LAInst Inst, RegisterClass StTy,
@@ -875,6 +893,18 @@ defm : StPat<truncstorei32, ST_W, GPR, i64>;
875893
defm : StPat<store, ST_D, GPR, i64>;
876894
} // Predicates = [IsLA64]
877895

896+
// LA64 register-register-addressed stores
897+
let Predicates = [IsLA64] in {
898+
class RegRegStPat<PatFrag StoreOp, LAInst Inst, RegisterClass StTy>
899+
: Pat<(StoreOp (i64 StTy:$rd), (add BaseAddr:$rj, GPR:$rk)),
900+
(Inst StTy:$rd, BaseAddr:$rj, GPR:$rk)>;
901+
902+
def : RegRegStPat<truncstorei8, STX_B, GPR>;
903+
def : RegRegStPat<truncstorei16, STX_H, GPR>;
904+
def : RegRegStPat<truncstorei32, STX_W, GPR>;
905+
def : RegRegStPat<store, STX_D, GPR>;
906+
} // Predicates = [IsLA64]
907+
878908
/// Atomic loads and stores
879909

880910
def : Pat<(atomic_fence timm, timm), (DBAR 0)>;

llvm/test/CodeGen/LoongArch/ir-instruction/load-store.ll

+248
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,183 @@ define i64 @ld_wu(ptr %a) nounwind {
226226
ret i64 %6
227227
}
228228

229+
define i64 @ldx_b(ptr %a, i64 %idx) nounwind {
230+
; LA32-LABEL: ldx_b:
231+
; LA32: # %bb.0:
232+
; LA32-NEXT: add.w $a1, $a0, $a1
233+
; LA32-NEXT: ld.b $a2, $a1, 0
234+
; LA32-NEXT: ld.b $a0, $a0, 0
235+
; LA32-NEXT: srai.w $a1, $a2, 31
236+
; LA32-NEXT: move $a0, $a2
237+
; LA32-NEXT: jirl $zero, $ra, 0
238+
;
239+
; LA64-LABEL: ldx_b:
240+
; LA64: # %bb.0:
241+
; LA64-NEXT: ldx.b $a1, $a0, $a1
242+
; LA64-NEXT: ld.b $a0, $a0, 0
243+
; LA64-NEXT: move $a0, $a1
244+
; LA64-NEXT: jirl $zero, $ra, 0
245+
%1 = getelementptr i8, ptr %a, i64 %idx
246+
%2 = load i8, ptr %1
247+
%3 = sext i8 %2 to i64
248+
%4 = load volatile i8, ptr %a
249+
ret i64 %3
250+
}
251+
252+
define i64 @ldx_h(ptr %a, i64 %idx) nounwind {
253+
; LA32-LABEL: ldx_h:
254+
; LA32: # %bb.0:
255+
; LA32-NEXT: slli.w $a1, $a1, 1
256+
; LA32-NEXT: add.w $a1, $a0, $a1
257+
; LA32-NEXT: ld.h $a2, $a1, 0
258+
; LA32-NEXT: ld.h $a0, $a0, 0
259+
; LA32-NEXT: srai.w $a1, $a2, 31
260+
; LA32-NEXT: move $a0, $a2
261+
; LA32-NEXT: jirl $zero, $ra, 0
262+
;
263+
; LA64-LABEL: ldx_h:
264+
; LA64: # %bb.0:
265+
; LA64-NEXT: slli.d $a1, $a1, 1
266+
; LA64-NEXT: ldx.h $a1, $a0, $a1
267+
; LA64-NEXT: ld.h $a0, $a0, 0
268+
; LA64-NEXT: move $a0, $a1
269+
; LA64-NEXT: jirl $zero, $ra, 0
270+
%1 = getelementptr i16, ptr %a, i64 %idx
271+
%2 = load i16, ptr %1
272+
%3 = sext i16 %2 to i64
273+
%4 = load volatile i16, ptr %a
274+
ret i64 %3
275+
}
276+
277+
define i64 @ldx_w(ptr %a, i64 %idx) nounwind {
278+
; LA32-LABEL: ldx_w:
279+
; LA32: # %bb.0:
280+
; LA32-NEXT: slli.w $a1, $a1, 2
281+
; LA32-NEXT: add.w $a1, $a0, $a1
282+
; LA32-NEXT: ld.w $a2, $a1, 0
283+
; LA32-NEXT: ld.w $a0, $a0, 0
284+
; LA32-NEXT: srai.w $a1, $a2, 31
285+
; LA32-NEXT: move $a0, $a2
286+
; LA32-NEXT: jirl $zero, $ra, 0
287+
;
288+
; LA64-LABEL: ldx_w:
289+
; LA64: # %bb.0:
290+
; LA64-NEXT: slli.d $a1, $a1, 2
291+
; LA64-NEXT: ldx.w $a1, $a0, $a1
292+
; LA64-NEXT: ld.w $a0, $a0, 0
293+
; LA64-NEXT: move $a0, $a1
294+
; LA64-NEXT: jirl $zero, $ra, 0
295+
%1 = getelementptr i32, ptr %a, i64 %idx
296+
%2 = load i32, ptr %1
297+
%3 = sext i32 %2 to i64
298+
%4 = load volatile i32, ptr %a
299+
ret i64 %3
300+
}
301+
302+
define i64 @ldx_d(ptr %a, i64 %idx) nounwind {
303+
; LA32-LABEL: ldx_d:
304+
; LA32: # %bb.0:
305+
; LA32-NEXT: slli.w $a1, $a1, 3
306+
; LA32-NEXT: add.w $a1, $a0, $a1
307+
; LA32-NEXT: ld.w $a2, $a1, 0
308+
; LA32-NEXT: ld.w $a3, $a0, 0
309+
; LA32-NEXT: ld.w $a1, $a1, 4
310+
; LA32-NEXT: ld.w $a0, $a0, 4
311+
; LA32-NEXT: move $a0, $a2
312+
; LA32-NEXT: jirl $zero, $ra, 0
313+
;
314+
; LA64-LABEL: ldx_d:
315+
; LA64: # %bb.0:
316+
; LA64-NEXT: slli.d $a1, $a1, 3
317+
; LA64-NEXT: ldx.d $a1, $a0, $a1
318+
; LA64-NEXT: ld.d $a0, $a0, 0
319+
; LA64-NEXT: move $a0, $a1
320+
; LA64-NEXT: jirl $zero, $ra, 0
321+
%1 = getelementptr i64, ptr %a, i64 %idx
322+
%2 = load i64, ptr %1
323+
%3 = load volatile i64, ptr %a
324+
ret i64 %2
325+
}
326+
327+
define i64 @ldx_bu(ptr %a, i64 %idx) nounwind {
328+
; LA32-LABEL: ldx_bu:
329+
; LA32: # %bb.0:
330+
; LA32-NEXT: add.w $a1, $a0, $a1
331+
; LA32-NEXT: ld.bu $a1, $a1, 0
332+
; LA32-NEXT: ld.bu $a0, $a0, 0
333+
; LA32-NEXT: add.w $a0, $a1, $a0
334+
; LA32-NEXT: sltu $a1, $a0, $a1
335+
; LA32-NEXT: jirl $zero, $ra, 0
336+
;
337+
; LA64-LABEL: ldx_bu:
338+
; LA64: # %bb.0:
339+
; LA64-NEXT: ldx.bu $a1, $a0, $a1
340+
; LA64-NEXT: ld.bu $a0, $a0, 0
341+
; LA64-NEXT: add.d $a0, $a1, $a0
342+
; LA64-NEXT: jirl $zero, $ra, 0
343+
%1 = getelementptr i8, ptr %a, i64 %idx
344+
%2 = load i8, ptr %1
345+
%3 = zext i8 %2 to i64
346+
%4 = load volatile i8, ptr %a
347+
%5 = zext i8 %4 to i64
348+
%6 = add i64 %3, %5
349+
ret i64 %6
350+
}
351+
352+
define i64 @ldx_hu(ptr %a, i64 %idx) nounwind {
353+
; LA32-LABEL: ldx_hu:
354+
; LA32: # %bb.0:
355+
; LA32-NEXT: slli.w $a1, $a1, 1
356+
; LA32-NEXT: add.w $a1, $a0, $a1
357+
; LA32-NEXT: ld.hu $a1, $a1, 0
358+
; LA32-NEXT: ld.hu $a0, $a0, 0
359+
; LA32-NEXT: add.w $a0, $a1, $a0
360+
; LA32-NEXT: sltu $a1, $a0, $a1
361+
; LA32-NEXT: jirl $zero, $ra, 0
362+
;
363+
; LA64-LABEL: ldx_hu:
364+
; LA64: # %bb.0:
365+
; LA64-NEXT: slli.d $a1, $a1, 1
366+
; LA64-NEXT: ldx.hu $a1, $a0, $a1
367+
; LA64-NEXT: ld.hu $a0, $a0, 0
368+
; LA64-NEXT: add.d $a0, $a1, $a0
369+
; LA64-NEXT: jirl $zero, $ra, 0
370+
%1 = getelementptr i16, ptr %a, i64 %idx
371+
%2 = load i16, ptr %1
372+
%3 = zext i16 %2 to i64
373+
%4 = load volatile i16, ptr %a
374+
%5 = zext i16 %4 to i64
375+
%6 = add i64 %3, %5
376+
ret i64 %6
377+
}
378+
379+
define i64 @ldx_wu(ptr %a, i64 %idx) nounwind {
380+
; LA32-LABEL: ldx_wu:
381+
; LA32: # %bb.0:
382+
; LA32-NEXT: slli.w $a1, $a1, 2
383+
; LA32-NEXT: add.w $a1, $a0, $a1
384+
; LA32-NEXT: ld.w $a1, $a1, 0
385+
; LA32-NEXT: ld.w $a0, $a0, 0
386+
; LA32-NEXT: add.w $a0, $a1, $a0
387+
; LA32-NEXT: sltu $a1, $a0, $a1
388+
; LA32-NEXT: jirl $zero, $ra, 0
389+
;
390+
; LA64-LABEL: ldx_wu:
391+
; LA64: # %bb.0:
392+
; LA64-NEXT: slli.d $a1, $a1, 2
393+
; LA64-NEXT: ldx.wu $a1, $a0, $a1
394+
; LA64-NEXT: ld.wu $a0, $a0, 0
395+
; LA64-NEXT: add.d $a0, $a1, $a0
396+
; LA64-NEXT: jirl $zero, $ra, 0
397+
%1 = getelementptr i32, ptr %a, i64 %idx
398+
%2 = load i32, ptr %1
399+
%3 = zext i32 %2 to i64
400+
%4 = load volatile i32, ptr %a
401+
%5 = zext i32 %4 to i64
402+
%6 = add i64 %3, %5
403+
ret i64 %6
404+
}
405+
229406
;; Check indexed and unindexed stores.
230407

231408
define void @st_b(ptr %a, i8 %b) nounwind {
@@ -284,6 +461,77 @@ define void @st_d(ptr %a, i64 %b) nounwind {
284461
ret void
285462
}
286463

464+
define void @stx_b(ptr %dst, i64 %idx, i8 %val) nounwind {
465+
; LA32-LABEL: stx_b:
466+
; LA32: # %bb.0:
467+
; LA32-NEXT: add.w $a0, $a0, $a1
468+
; LA32-NEXT: st.b $a3, $a0, 0
469+
; LA32-NEXT: jirl $zero, $ra, 0
470+
;
471+
; LA64-LABEL: stx_b:
472+
; LA64: # %bb.0:
473+
; LA64-NEXT: stx.b $a2, $a0, $a1
474+
; LA64-NEXT: jirl $zero, $ra, 0
475+
%1 = getelementptr i8, ptr %dst, i64 %idx
476+
store i8 %val, ptr %1
477+
ret void
478+
}
479+
480+
define void @stx_h(ptr %dst, i64 %idx, i16 %val) nounwind {
481+
; LA32-LABEL: stx_h:
482+
; LA32: # %bb.0:
483+
; LA32-NEXT: slli.w $a1, $a1, 1
484+
; LA32-NEXT: add.w $a0, $a0, $a1
485+
; LA32-NEXT: st.h $a3, $a0, 0
486+
; LA32-NEXT: jirl $zero, $ra, 0
487+
;
488+
; LA64-LABEL: stx_h:
489+
; LA64: # %bb.0:
490+
; LA64-NEXT: slli.d $a1, $a1, 1
491+
; LA64-NEXT: stx.h $a2, $a0, $a1
492+
; LA64-NEXT: jirl $zero, $ra, 0
493+
%1 = getelementptr i16, ptr %dst, i64 %idx
494+
store i16 %val, ptr %1
495+
ret void
496+
}
497+
498+
define void @stx_w(ptr %dst, i64 %idx, i32 %val) nounwind {
499+
; LA32-LABEL: stx_w:
500+
; LA32: # %bb.0:
501+
; LA32-NEXT: slli.w $a1, $a1, 2
502+
; LA32-NEXT: add.w $a0, $a0, $a1
503+
; LA32-NEXT: st.w $a3, $a0, 0
504+
; LA32-NEXT: jirl $zero, $ra, 0
505+
;
506+
; LA64-LABEL: stx_w:
507+
; LA64: # %bb.0:
508+
; LA64-NEXT: slli.d $a1, $a1, 2
509+
; LA64-NEXT: stx.w $a2, $a0, $a1
510+
; LA64-NEXT: jirl $zero, $ra, 0
511+
%1 = getelementptr i32, ptr %dst, i64 %idx
512+
store i32 %val, ptr %1
513+
ret void
514+
}
515+
516+
define void @stx_d(ptr %dst, i64 %idx, i64 %val) nounwind {
517+
; LA32-LABEL: stx_d:
518+
; LA32: # %bb.0:
519+
; LA32-NEXT: slli.w $a1, $a1, 3
520+
; LA32-NEXT: add.w $a0, $a0, $a1
521+
; LA32-NEXT: st.w $a4, $a0, 4
522+
; LA32-NEXT: st.w $a3, $a0, 0
523+
; LA32-NEXT: jirl $zero, $ra, 0
524+
;
525+
; LA64-LABEL: stx_d:
526+
; LA64: # %bb.0:
527+
; LA64-NEXT: slli.d $a1, $a1, 3
528+
; LA64-NEXT: stx.d $a2, $a0, $a1
529+
; LA64-NEXT: jirl $zero, $ra, 0
530+
%1 = getelementptr i64, ptr %dst, i64 %idx
531+
store i64 %val, ptr %1
532+
ret void
533+
}
534+
287535
;; Check load from and store to an i1 location.
288536
define i64 @load_sext_zext_anyext_i1(ptr %a) nounwind {
289537
;; sextload i1

0 commit comments

Comments
 (0)