| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py | 
 | ; RUN: llc -mtriple=riscv32 -mattr=+xtheadmempair -verify-machineinstrs < %s \ | 
 | ; RUN:   | FileCheck %s -check-prefix=RV32XTHEADMEMPAIR | 
 | ; RUN: llc -mtriple=riscv64 -mattr=+xtheadmempair -verify-machineinstrs < %s \ | 
 | ; RUN:   | FileCheck %s -check-prefix=RV64XTHEADMEMPAIR | 
 |  | 
 | define i64 @lwd(ptr %a) { | 
 | ; RV32XTHEADMEMPAIR-LABEL: lwd: | 
 | ; RV32XTHEADMEMPAIR:       # %bb.0: | 
 | ; RV32XTHEADMEMPAIR-NEXT:    th.lwd a1, a2, (a0), 2, 3 | 
 | ; RV32XTHEADMEMPAIR-NEXT:    srai a3, a1, 31 | 
 | ; RV32XTHEADMEMPAIR-NEXT:    srai a4, a2, 31 | 
 | ; RV32XTHEADMEMPAIR-NEXT:    add a0, a1, a2 | 
 | ; RV32XTHEADMEMPAIR-NEXT:    sltu a1, a0, a1 | 
 | ; RV32XTHEADMEMPAIR-NEXT:    add a3, a3, a4 | 
 | ; RV32XTHEADMEMPAIR-NEXT:    add a1, a3, a1 | 
 | ; RV32XTHEADMEMPAIR-NEXT:    ret | 
 | ; | 
 | ; RV64XTHEADMEMPAIR-LABEL: lwd: | 
 | ; RV64XTHEADMEMPAIR:       # %bb.0: | 
 | ; RV64XTHEADMEMPAIR-NEXT:    th.lwd a1, a2, (a0), 2, 3 | 
 | ; RV64XTHEADMEMPAIR-NEXT:    add a0, a1, a2 | 
 | ; RV64XTHEADMEMPAIR-NEXT:    ret | 
 |   %1 = getelementptr i32, ptr %a, i64 4 | 
 |   %2 = load i32, ptr %1, align 4 | 
 |   %3 = getelementptr i32, ptr %a, i64 5 | 
 |   %4 = load i32, ptr %3, align 4 | 
 |   %5 = sext i32 %2 to i64 | 
 |   %6 = sext i32 %4 to i64 | 
 |   %7 = add i64 %5, %6 | 
 |   ret i64 %7 | 
 | } | 
 |  | 
 | define i64 @lwud(ptr %a) { | 
 | ; RV32XTHEADMEMPAIR-LABEL: lwud: | 
 | ; RV32XTHEADMEMPAIR:       # %bb.0: | 
 | ; RV32XTHEADMEMPAIR-NEXT:    th.lwd a1, a2, (a0), 2, 3 | 
 | ; RV32XTHEADMEMPAIR-NEXT:    add a0, a1, a2 | 
 | ; RV32XTHEADMEMPAIR-NEXT:    sltu a1, a0, a1 | 
 | ; RV32XTHEADMEMPAIR-NEXT:    ret | 
 | ; | 
 | ; RV64XTHEADMEMPAIR-LABEL: lwud: | 
 | ; RV64XTHEADMEMPAIR:       # %bb.0: | 
 | ; RV64XTHEADMEMPAIR-NEXT:    th.lwud a1, a2, (a0), 2, 3 | 
 | ; RV64XTHEADMEMPAIR-NEXT:    add a0, a1, a2 | 
 | ; RV64XTHEADMEMPAIR-NEXT:    ret | 
 |   %1 = getelementptr i32, ptr %a, i64 4 | 
 |   %2 = load i32, ptr %1, align 4 | 
 |   %3 = getelementptr i32, ptr %a, i64 5 | 
 |   %4 = load i32, ptr %3, align 4 | 
 |   %5 = zext i32 %2 to i64 | 
 |   %6 = zext i32 %4 to i64 | 
 |   %7 = add i64 %5, %6 | 
 |   ret i64 %7 | 
 | } | 
 |  | 
 | define i64 @ldd(ptr %a) { | 
 | ; RV32XTHEADMEMPAIR-LABEL: ldd: | 
 | ; RV32XTHEADMEMPAIR:       # %bb.0: | 
 | ; RV32XTHEADMEMPAIR-NEXT:    lw a1, 32(a0) | 
 | ; RV32XTHEADMEMPAIR-NEXT:    lw a2, 36(a0) | 
 | ; RV32XTHEADMEMPAIR-NEXT:    lw a3, 44(a0) | 
 | ; RV32XTHEADMEMPAIR-NEXT:    lw a0, 40(a0) | 
 | ; RV32XTHEADMEMPAIR-NEXT:    add a2, a2, a3 | 
 | ; RV32XTHEADMEMPAIR-NEXT:    add a0, a1, a0 | 
 | ; RV32XTHEADMEMPAIR-NEXT:    sltu a1, a0, a1 | 
 | ; RV32XTHEADMEMPAIR-NEXT:    add a1, a2, a1 | 
 | ; RV32XTHEADMEMPAIR-NEXT:    ret | 
 | ; | 
 | ; RV64XTHEADMEMPAIR-LABEL: ldd: | 
 | ; RV64XTHEADMEMPAIR:       # %bb.0: | 
 | ; RV64XTHEADMEMPAIR-NEXT:    th.ldd a1, a2, (a0), 2, 4 | 
 | ; RV64XTHEADMEMPAIR-NEXT:    add a0, a1, a2 | 
 | ; RV64XTHEADMEMPAIR-NEXT:    ret | 
 |   %1 = getelementptr i64, ptr %a, i64 4 | 
 |   %2 = load i64, ptr %1, align 8 | 
 |   %3 = getelementptr i64, ptr %a, i64 5 | 
 |   %4 = load i64, ptr %3, align 8 | 
 |   %5 = add i64 %2, %4 | 
 |   ret i64 %5 | 
 | } | 
 |  | 
 | define i64 @lwd_0(ptr %a) { | 
 | ; RV32XTHEADMEMPAIR-LABEL: lwd_0: | 
 | ; RV32XTHEADMEMPAIR:       # %bb.0: | 
 | ; RV32XTHEADMEMPAIR-NEXT:    th.lwd a1, a2, (a0), 0, 3 | 
 | ; RV32XTHEADMEMPAIR-NEXT:    srai a3, a1, 31 | 
 | ; RV32XTHEADMEMPAIR-NEXT:    srai a4, a2, 31 | 
 | ; RV32XTHEADMEMPAIR-NEXT:    add a0, a1, a2 | 
 | ; RV32XTHEADMEMPAIR-NEXT:    sltu a1, a0, a1 | 
 | ; RV32XTHEADMEMPAIR-NEXT:    add a3, a3, a4 | 
 | ; RV32XTHEADMEMPAIR-NEXT:    add a1, a3, a1 | 
 | ; RV32XTHEADMEMPAIR-NEXT:    ret | 
 | ; | 
 | ; RV64XTHEADMEMPAIR-LABEL: lwd_0: | 
 | ; RV64XTHEADMEMPAIR:       # %bb.0: | 
 | ; RV64XTHEADMEMPAIR-NEXT:    th.lwd a1, a2, (a0), 0, 3 | 
 | ; RV64XTHEADMEMPAIR-NEXT:    add a0, a1, a2 | 
 | ; RV64XTHEADMEMPAIR-NEXT:    ret | 
 |   %1 = getelementptr i32, ptr %a, i64 0 | 
 |   %2 = load i32, ptr %1, align 4 | 
 |   %3 = getelementptr i32, ptr %a, i64 1 | 
 |   %4 = load i32, ptr %3, align 4 | 
 |   %5 = sext i32 %2 to i64 | 
 |   %6 = sext i32 %4 to i64 | 
 |   %7 = add i64 %5, %6 | 
 |   ret i64 %7 | 
 | } | 
 |  | 
 | define i64 @lwud_0(ptr %a) { | 
 | ; RV32XTHEADMEMPAIR-LABEL: lwud_0: | 
 | ; RV32XTHEADMEMPAIR:       # %bb.0: | 
 | ; RV32XTHEADMEMPAIR-NEXT:    th.lwd a1, a2, (a0), 0, 3 | 
 | ; RV32XTHEADMEMPAIR-NEXT:    add a0, a1, a2 | 
 | ; RV32XTHEADMEMPAIR-NEXT:    sltu a1, a0, a1 | 
 | ; RV32XTHEADMEMPAIR-NEXT:    ret | 
 | ; | 
 | ; RV64XTHEADMEMPAIR-LABEL: lwud_0: | 
 | ; RV64XTHEADMEMPAIR:       # %bb.0: | 
 | ; RV64XTHEADMEMPAIR-NEXT:    th.lwud a1, a2, (a0), 0, 3 | 
 | ; RV64XTHEADMEMPAIR-NEXT:    add a0, a1, a2 | 
 | ; RV64XTHEADMEMPAIR-NEXT:    ret | 
 |   %1 = getelementptr i32, ptr %a, i64 0 | 
 |   %2 = load i32, ptr %1, align 4 | 
 |   %3 = getelementptr i32, ptr %a, i64 1 | 
 |   %4 = load i32, ptr %3, align 4 | 
 |   %5 = zext i32 %2 to i64 | 
 |   %6 = zext i32 %4 to i64 | 
 |   %7 = add i64 %5, %6 | 
 |   ret i64 %7 | 
 | } | 
 |  | 
 | define i64 @ldd_0(ptr %a) { | 
 | ; RV32XTHEADMEMPAIR-LABEL: ldd_0: | 
 | ; RV32XTHEADMEMPAIR:       # %bb.0: | 
 | ; RV32XTHEADMEMPAIR-NEXT:    th.lwd a1, a2, (a0), 0, 3 | 
 | ; RV32XTHEADMEMPAIR-NEXT:    th.lwd a3, a4, (a0), 1, 3 | 
 | ; RV32XTHEADMEMPAIR-NEXT:    add a2, a2, a4 | 
 | ; RV32XTHEADMEMPAIR-NEXT:    add a0, a1, a3 | 
 | ; RV32XTHEADMEMPAIR-NEXT:    sltu a1, a0, a1 | 
 | ; RV32XTHEADMEMPAIR-NEXT:    add a1, a2, a1 | 
 | ; RV32XTHEADMEMPAIR-NEXT:    ret | 
 | ; | 
 | ; RV64XTHEADMEMPAIR-LABEL: ldd_0: | 
 | ; RV64XTHEADMEMPAIR:       # %bb.0: | 
 | ; RV64XTHEADMEMPAIR-NEXT:    th.ldd a1, a2, (a0), 0, 4 | 
 | ; RV64XTHEADMEMPAIR-NEXT:    add a0, a1, a2 | 
 | ; RV64XTHEADMEMPAIR-NEXT:    ret | 
 |   %1 = getelementptr i64, ptr %a, i64 0 | 
 |   %2 = load i64, ptr %1, align 8 | 
 |   %3 = getelementptr i64, ptr %a, i64 1 | 
 |   %4 = load i64, ptr %3, align 8 | 
 |   %5 = add i64 %2, %4 | 
 |   ret i64 %5 | 
 | } | 
 |  | 
 | define void @swd(ptr %a, i32 %b, i32%c) { | 
 | ; RV32XTHEADMEMPAIR-LABEL: swd: | 
 | ; RV32XTHEADMEMPAIR:       # %bb.0: | 
 | ; RV32XTHEADMEMPAIR-NEXT:    th.swd a1, a2, (a0), 2, 3 | 
 | ; RV32XTHEADMEMPAIR-NEXT:    ret | 
 | ; | 
 | ; RV64XTHEADMEMPAIR-LABEL: swd: | 
 | ; RV64XTHEADMEMPAIR:       # %bb.0: | 
 | ; RV64XTHEADMEMPAIR-NEXT:    th.swd a1, a2, (a0), 2, 3 | 
 | ; RV64XTHEADMEMPAIR-NEXT:    ret | 
 |   %1 = getelementptr i32, ptr %a, i64 4 | 
 |   store i32 %b, ptr %1, align 4 | 
 |   %2 = getelementptr i32, ptr %a, i64 5 | 
 |   store i32 %c, ptr %2, align 4 | 
 |   ret void | 
 | } | 
 |  | 
 | define void @sdd(ptr %a, i64 %b, i64%c) { | 
 | ; RV32XTHEADMEMPAIR-LABEL: sdd: | 
 | ; RV32XTHEADMEMPAIR:       # %bb.0: | 
 | ; RV32XTHEADMEMPAIR-NEXT:    sw a2, 36(a0) | 
 | ; RV32XTHEADMEMPAIR-NEXT:    sw a1, 32(a0) | 
 | ; RV32XTHEADMEMPAIR-NEXT:    sw a4, 44(a0) | 
 | ; RV32XTHEADMEMPAIR-NEXT:    sw a3, 40(a0) | 
 | ; RV32XTHEADMEMPAIR-NEXT:    ret | 
 | ; | 
 | ; RV64XTHEADMEMPAIR-LABEL: sdd: | 
 | ; RV64XTHEADMEMPAIR:       # %bb.0: | 
 | ; RV64XTHEADMEMPAIR-NEXT:    th.sdd a1, a2, (a0), 2, 4 | 
 | ; RV64XTHEADMEMPAIR-NEXT:    ret | 
 |   %1 = getelementptr i64, ptr %a, i64 4 | 
 |   store i64 %b, ptr %1, align 8 | 
 |   %2 = getelementptr i64, ptr %a, i64 5 | 
 |   store i64 %c, ptr %2, align 8 | 
 |   ret void | 
 | } | 
 |  | 
 | define void @swd_0(ptr %a, i32 %b, i32%c) { | 
 | ; RV32XTHEADMEMPAIR-LABEL: swd_0: | 
 | ; RV32XTHEADMEMPAIR:       # %bb.0: | 
 | ; RV32XTHEADMEMPAIR-NEXT:    th.swd a1, a2, (a0), 0, 3 | 
 | ; RV32XTHEADMEMPAIR-NEXT:    ret | 
 | ; | 
 | ; RV64XTHEADMEMPAIR-LABEL: swd_0: | 
 | ; RV64XTHEADMEMPAIR:       # %bb.0: | 
 | ; RV64XTHEADMEMPAIR-NEXT:    th.swd a1, a2, (a0), 0, 3 | 
 | ; RV64XTHEADMEMPAIR-NEXT:    ret | 
 |   %1 = getelementptr i32, ptr %a, i64 0 | 
 |   store i32 %b, ptr %1, align 4 | 
 |   %2 = getelementptr i32, ptr %a, i64 1 | 
 |   store i32 %c, ptr %2, align 4 | 
 |   ret void | 
 | } | 
 |  | 
 | define void @sdd_0(ptr %a, i64 %b, i64%c) { | 
 | ; RV32XTHEADMEMPAIR-LABEL: sdd_0: | 
 | ; RV32XTHEADMEMPAIR:       # %bb.0: | 
 | ; RV32XTHEADMEMPAIR-NEXT:    th.swd a1, a2, (a0), 0, 3 | 
 | ; RV32XTHEADMEMPAIR-NEXT:    th.swd a3, a4, (a0), 1, 3 | 
 | ; RV32XTHEADMEMPAIR-NEXT:    ret | 
 | ; | 
 | ; RV64XTHEADMEMPAIR-LABEL: sdd_0: | 
 | ; RV64XTHEADMEMPAIR:       # %bb.0: | 
 | ; RV64XTHEADMEMPAIR-NEXT:    th.sdd a1, a2, (a0), 0, 4 | 
 | ; RV64XTHEADMEMPAIR-NEXT:    ret | 
 |   %1 = getelementptr i64, ptr %a, i64 0 | 
 |   store i64 %b, ptr %1, align 8 | 
 |   %2 = getelementptr i64, ptr %a, i64 1 | 
 |   store i64 %c, ptr %2, align 8 | 
 |   ret void | 
 | } | 
 |  | 
 | define i64 @ld64(ptr %a) { | 
 | ; RV32XTHEADMEMPAIR-LABEL: ld64: | 
 | ; RV32XTHEADMEMPAIR:       # %bb.0: | 
 | ; RV32XTHEADMEMPAIR-NEXT:    th.lwd a2, a1, (a0), 0, 3 | 
 | ; RV32XTHEADMEMPAIR-NEXT:    mv a0, a2 | 
 | ; RV32XTHEADMEMPAIR-NEXT:    ret | 
 | ; | 
 | ; RV64XTHEADMEMPAIR-LABEL: ld64: | 
 | ; RV64XTHEADMEMPAIR:       # %bb.0: | 
 | ; RV64XTHEADMEMPAIR-NEXT:    ld a0, 0(a0) | 
 | ; RV64XTHEADMEMPAIR-NEXT:    ret | 
 |   %1 = getelementptr i64, ptr %a, i64 0 | 
 |   %2 = load i64, ptr %1, align 8 | 
 |   ret i64 %2 | 
 | } | 
 |  | 
 | define i128 @ld128(ptr %a) { | 
 | ; RV32XTHEADMEMPAIR-LABEL: ld128: | 
 | ; RV32XTHEADMEMPAIR:       # %bb.0: | 
 | ; RV32XTHEADMEMPAIR-NEXT:    th.lwd a2, a3, (a1), 1, 3 | 
 | ; RV32XTHEADMEMPAIR-NEXT:    th.lwd a4, a5, (a1), 0, 3 | 
 | ; RV32XTHEADMEMPAIR-NEXT:    th.swd a2, a3, (a0), 1, 3 | 
 | ; RV32XTHEADMEMPAIR-NEXT:    th.swd a4, a5, (a0), 0, 3 | 
 | ; RV32XTHEADMEMPAIR-NEXT:    ret | 
 | ; | 
 | ; RV64XTHEADMEMPAIR-LABEL: ld128: | 
 | ; RV64XTHEADMEMPAIR:       # %bb.0: | 
 | ; RV64XTHEADMEMPAIR-NEXT:    th.ldd a2, a1, (a0), 0, 4 | 
 | ; RV64XTHEADMEMPAIR-NEXT:    mv a0, a2 | 
 | ; RV64XTHEADMEMPAIR-NEXT:    ret | 
 |   %1 = getelementptr i128, ptr %a, i64 0 | 
 |   %2 = load i128, ptr %1, align 8 | 
 |   ret i128 %2 | 
 | } | 
 |  | 
 | define void @sd64(ptr %a, i64 %b) { | 
 | ; RV32XTHEADMEMPAIR-LABEL: sd64: | 
 | ; RV32XTHEADMEMPAIR:       # %bb.0: | 
 | ; RV32XTHEADMEMPAIR-NEXT:    th.swd a1, a2, (a0), 0, 3 | 
 | ; RV32XTHEADMEMPAIR-NEXT:    ret | 
 | ; | 
 | ; RV64XTHEADMEMPAIR-LABEL: sd64: | 
 | ; RV64XTHEADMEMPAIR:       # %bb.0: | 
 | ; RV64XTHEADMEMPAIR-NEXT:    sd a1, 0(a0) | 
 | ; RV64XTHEADMEMPAIR-NEXT:    ret | 
 |   %1 = getelementptr i64, ptr %a, i64 0 | 
 |   store i64 %b, ptr %1, align 8 | 
 |   ret void | 
 | } | 
 |  | 
 | define void @sd128(ptr %a, i128 %b) { | 
 | ; RV32XTHEADMEMPAIR-LABEL: sd128: | 
 | ; RV32XTHEADMEMPAIR:       # %bb.0: | 
 | ; RV32XTHEADMEMPAIR-NEXT:    th.lwd a2, a3, (a1), 1, 3 | 
 | ; RV32XTHEADMEMPAIR-NEXT:    th.lwd a4, a5, (a1), 0, 3 | 
 | ; RV32XTHEADMEMPAIR-NEXT:    th.swd a2, a3, (a0), 1, 3 | 
 | ; RV32XTHEADMEMPAIR-NEXT:    th.swd a4, a5, (a0), 0, 3 | 
 | ; RV32XTHEADMEMPAIR-NEXT:    ret | 
 | ; | 
 | ; RV64XTHEADMEMPAIR-LABEL: sd128: | 
 | ; RV64XTHEADMEMPAIR:       # %bb.0: | 
 | ; RV64XTHEADMEMPAIR-NEXT:    th.sdd a1, a2, (a0), 0, 4 | 
 | ; RV64XTHEADMEMPAIR-NEXT:    ret | 
 |   %1 = getelementptr i128, ptr %a, i64 0 | 
 |   store i128 %b, ptr %1, align 8 | 
 |   ret void | 
 | } | 
 |  | 
 | define i32 @lh(ptr %a) { | 
 | ; RV32XTHEADMEMPAIR-LABEL: lh: | 
 | ; RV32XTHEADMEMPAIR:       # %bb.0: | 
 | ; RV32XTHEADMEMPAIR-NEXT:    lh a1, 0(a0) | 
 | ; RV32XTHEADMEMPAIR-NEXT:    lh a0, 2(a0) | 
 | ; RV32XTHEADMEMPAIR-NEXT:    add a0, a1, a0 | 
 | ; RV32XTHEADMEMPAIR-NEXT:    ret | 
 | ; | 
 | ; RV64XTHEADMEMPAIR-LABEL: lh: | 
 | ; RV64XTHEADMEMPAIR:       # %bb.0: | 
 | ; RV64XTHEADMEMPAIR-NEXT:    lh a1, 0(a0) | 
 | ; RV64XTHEADMEMPAIR-NEXT:    lh a0, 2(a0) | 
 | ; RV64XTHEADMEMPAIR-NEXT:    add a0, a1, a0 | 
 | ; RV64XTHEADMEMPAIR-NEXT:    ret | 
 |   %1 = getelementptr i16, ptr %a, i64 0 | 
 |   %2 = load i16, ptr %1, align 4 | 
 |   %3 = getelementptr i16, ptr %a, i64 1 | 
 |   %4 = load i16, ptr %3, align 4 | 
 |   %5 = sext i16 %2 to i32 | 
 |   %6 = sext i16 %4 to i32 | 
 |   %7 = add i32 %5, %6 | 
 |   ret i32 %7 | 
 | } | 
 |  | 
 | define i32 @lb(ptr %a) { | 
 | ; RV32XTHEADMEMPAIR-LABEL: lb: | 
 | ; RV32XTHEADMEMPAIR:       # %bb.0: | 
 | ; RV32XTHEADMEMPAIR-NEXT:    lb a1, 0(a0) | 
 | ; RV32XTHEADMEMPAIR-NEXT:    lb a0, 1(a0) | 
 | ; RV32XTHEADMEMPAIR-NEXT:    add a0, a1, a0 | 
 | ; RV32XTHEADMEMPAIR-NEXT:    ret | 
 | ; | 
 | ; RV64XTHEADMEMPAIR-LABEL: lb: | 
 | ; RV64XTHEADMEMPAIR:       # %bb.0: | 
 | ; RV64XTHEADMEMPAIR-NEXT:    lb a1, 0(a0) | 
 | ; RV64XTHEADMEMPAIR-NEXT:    lb a0, 1(a0) | 
 | ; RV64XTHEADMEMPAIR-NEXT:    add a0, a1, a0 | 
 | ; RV64XTHEADMEMPAIR-NEXT:    ret | 
 |   %1 = getelementptr i8, ptr %a, i64 0 | 
 |   %2 = load i8, ptr %1, align 4 | 
 |   %3 = getelementptr i8, ptr %a, i64 1 | 
 |   %4 = load i8, ptr %3, align 4 | 
 |   %5 = sext i8 %2 to i32 | 
 |   %6 = sext i8 %4 to i32 | 
 |   %7 = add i32 %5, %6 | 
 |   ret i32 %7 | 
 | } |