1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=riscv32 -mattr=+xtheadmempair -verify-machineinstrs < %s \ 3; RUN: | FileCheck %s -check-prefix=RV32XTHEADMEMPAIR 4; RUN: llc -mtriple=riscv64 -mattr=+xtheadmempair -verify-machineinstrs < %s \ 5; RUN: | FileCheck %s -check-prefix=RV64XTHEADMEMPAIR 6 7define i64 @lwd(ptr %a) { 8; RV32XTHEADMEMPAIR-LABEL: lwd: 9; RV32XTHEADMEMPAIR: # %bb.0: 10; RV32XTHEADMEMPAIR-NEXT: th.lwd a1, a2, (a0), 2, 3 11; RV32XTHEADMEMPAIR-NEXT: srai a3, a1, 31 12; RV32XTHEADMEMPAIR-NEXT: srai a4, a2, 31 13; RV32XTHEADMEMPAIR-NEXT: add a0, a1, a2 14; RV32XTHEADMEMPAIR-NEXT: sltu a1, a0, a1 15; RV32XTHEADMEMPAIR-NEXT: add a3, a3, a4 16; RV32XTHEADMEMPAIR-NEXT: add a1, a3, a1 17; RV32XTHEADMEMPAIR-NEXT: ret 18; 19; RV64XTHEADMEMPAIR-LABEL: lwd: 20; RV64XTHEADMEMPAIR: # %bb.0: 21; RV64XTHEADMEMPAIR-NEXT: th.lwd a1, a2, (a0), 2, 3 22; RV64XTHEADMEMPAIR-NEXT: add a0, a1, a2 23; RV64XTHEADMEMPAIR-NEXT: ret 24 %1 = getelementptr i32, ptr %a, i64 4 25 %2 = load i32, ptr %1, align 4 26 %3 = getelementptr i32, ptr %a, i64 5 27 %4 = load i32, ptr %3, align 4 28 %5 = sext i32 %2 to i64 29 %6 = sext i32 %4 to i64 30 %7 = add i64 %5, %6 31 ret i64 %7 32} 33 34define i64 @lwud(ptr %a) { 35; RV32XTHEADMEMPAIR-LABEL: lwud: 36; RV32XTHEADMEMPAIR: # %bb.0: 37; RV32XTHEADMEMPAIR-NEXT: th.lwd a1, a2, (a0), 2, 3 38; RV32XTHEADMEMPAIR-NEXT: add a0, a1, a2 39; RV32XTHEADMEMPAIR-NEXT: sltu a1, a0, a1 40; RV32XTHEADMEMPAIR-NEXT: ret 41; 42; RV64XTHEADMEMPAIR-LABEL: lwud: 43; RV64XTHEADMEMPAIR: # %bb.0: 44; RV64XTHEADMEMPAIR-NEXT: th.lwud a1, a2, (a0), 2, 3 45; RV64XTHEADMEMPAIR-NEXT: add a0, a1, a2 46; RV64XTHEADMEMPAIR-NEXT: ret 47 %1 = getelementptr i32, ptr %a, i64 4 48 %2 = load i32, ptr %1, align 4 49 %3 = getelementptr i32, ptr %a, i64 5 50 %4 = load i32, ptr %3, align 4 51 %5 = zext i32 %2 to i64 52 %6 = zext i32 %4 to i64 53 %7 = add i64 %5, %6 54 ret i64 %7 55} 56 57define i64 @ldd(ptr %a) { 58; RV32XTHEADMEMPAIR-LABEL: ldd: 59; RV32XTHEADMEMPAIR: # %bb.0: 60; RV32XTHEADMEMPAIR-NEXT: lw a1, 44(a0) 61; RV32XTHEADMEMPAIR-NEXT: lw a2, 32(a0) 62; RV32XTHEADMEMPAIR-NEXT: lw a3, 36(a0) 63; RV32XTHEADMEMPAIR-NEXT: lw a0, 40(a0) 64; RV32XTHEADMEMPAIR-NEXT: add a1, a3, a1 65; RV32XTHEADMEMPAIR-NEXT: add a0, a2, a0 66; RV32XTHEADMEMPAIR-NEXT: sltu a2, a0, a2 67; RV32XTHEADMEMPAIR-NEXT: add a1, a1, a2 68; RV32XTHEADMEMPAIR-NEXT: ret 69; 70; RV64XTHEADMEMPAIR-LABEL: ldd: 71; RV64XTHEADMEMPAIR: # %bb.0: 72; RV64XTHEADMEMPAIR-NEXT: th.ldd a1, a2, (a0), 2, 4 73; RV64XTHEADMEMPAIR-NEXT: add a0, a1, a2 74; RV64XTHEADMEMPAIR-NEXT: ret 75 %1 = getelementptr i64, ptr %a, i64 4 76 %2 = load i64, ptr %1, align 8 77 %3 = getelementptr i64, ptr %a, i64 5 78 %4 = load i64, ptr %3, align 8 79 %5 = add i64 %2, %4 80 ret i64 %5 81} 82 83define i64 @lwd_0(ptr %a) { 84; RV32XTHEADMEMPAIR-LABEL: lwd_0: 85; RV32XTHEADMEMPAIR: # %bb.0: 86; RV32XTHEADMEMPAIR-NEXT: th.lwd a1, a2, (a0), 0, 3 87; RV32XTHEADMEMPAIR-NEXT: srai a3, a1, 31 88; RV32XTHEADMEMPAIR-NEXT: srai a4, a2, 31 89; RV32XTHEADMEMPAIR-NEXT: add a0, a1, a2 90; RV32XTHEADMEMPAIR-NEXT: sltu a1, a0, a1 91; RV32XTHEADMEMPAIR-NEXT: add a3, a3, a4 92; RV32XTHEADMEMPAIR-NEXT: add a1, a3, a1 93; RV32XTHEADMEMPAIR-NEXT: ret 94; 95; RV64XTHEADMEMPAIR-LABEL: lwd_0: 96; RV64XTHEADMEMPAIR: # %bb.0: 97; RV64XTHEADMEMPAIR-NEXT: th.lwd a1, a2, (a0), 0, 3 98; RV64XTHEADMEMPAIR-NEXT: add a0, a1, a2 99; RV64XTHEADMEMPAIR-NEXT: ret 100 %1 = getelementptr i32, ptr %a, i64 0 101 %2 = load i32, ptr %1, align 4 102 %3 = getelementptr i32, ptr %a, i64 1 103 %4 = load i32, ptr %3, align 4 104 %5 = sext i32 %2 to i64 105 %6 = sext i32 %4 to i64 106 %7 = add i64 %5, %6 107 ret i64 %7 108} 109 110define i64 @lwud_0(ptr %a) { 111; RV32XTHEADMEMPAIR-LABEL: lwud_0: 112; RV32XTHEADMEMPAIR: # %bb.0: 113; RV32XTHEADMEMPAIR-NEXT: th.lwd a1, a2, (a0), 0, 3 114; RV32XTHEADMEMPAIR-NEXT: add a0, a1, a2 115; RV32XTHEADMEMPAIR-NEXT: sltu a1, a0, a1 116; RV32XTHEADMEMPAIR-NEXT: ret 117; 118; RV64XTHEADMEMPAIR-LABEL: lwud_0: 119; RV64XTHEADMEMPAIR: # %bb.0: 120; RV64XTHEADMEMPAIR-NEXT: th.lwud a1, a2, (a0), 0, 3 121; RV64XTHEADMEMPAIR-NEXT: add a0, a1, a2 122; RV64XTHEADMEMPAIR-NEXT: ret 123 %1 = getelementptr i32, ptr %a, i64 0 124 %2 = load i32, ptr %1, align 4 125 %3 = getelementptr i32, ptr %a, i64 1 126 %4 = load i32, ptr %3, align 4 127 %5 = zext i32 %2 to i64 128 %6 = zext i32 %4 to i64 129 %7 = add i64 %5, %6 130 ret i64 %7 131} 132 133define i64 @ldd_0(ptr %a) { 134; RV32XTHEADMEMPAIR-LABEL: ldd_0: 135; RV32XTHEADMEMPAIR: # %bb.0: 136; RV32XTHEADMEMPAIR-NEXT: th.lwd a1, a2, (a0), 0, 3 137; RV32XTHEADMEMPAIR-NEXT: th.lwd a3, a4, (a0), 1, 3 138; RV32XTHEADMEMPAIR-NEXT: add a2, a2, a4 139; RV32XTHEADMEMPAIR-NEXT: add a0, a1, a3 140; RV32XTHEADMEMPAIR-NEXT: sltu a1, a0, a1 141; RV32XTHEADMEMPAIR-NEXT: add a1, a2, a1 142; RV32XTHEADMEMPAIR-NEXT: ret 143; 144; RV64XTHEADMEMPAIR-LABEL: ldd_0: 145; RV64XTHEADMEMPAIR: # %bb.0: 146; RV64XTHEADMEMPAIR-NEXT: th.ldd a1, a2, (a0), 0, 4 147; RV64XTHEADMEMPAIR-NEXT: add a0, a1, a2 148; RV64XTHEADMEMPAIR-NEXT: ret 149 %1 = getelementptr i64, ptr %a, i64 0 150 %2 = load i64, ptr %1, align 8 151 %3 = getelementptr i64, ptr %a, i64 1 152 %4 = load i64, ptr %3, align 8 153 %5 = add i64 %2, %4 154 ret i64 %5 155} 156 157define void @swd(ptr %a, i32 %b, i32%c) { 158; RV32XTHEADMEMPAIR-LABEL: swd: 159; RV32XTHEADMEMPAIR: # %bb.0: 160; RV32XTHEADMEMPAIR-NEXT: th.swd a1, a2, (a0), 2, 3 161; RV32XTHEADMEMPAIR-NEXT: ret 162; 163; RV64XTHEADMEMPAIR-LABEL: swd: 164; RV64XTHEADMEMPAIR: # %bb.0: 165; RV64XTHEADMEMPAIR-NEXT: th.swd a1, a2, (a0), 2, 3 166; RV64XTHEADMEMPAIR-NEXT: ret 167 %1 = getelementptr i32, ptr %a, i64 4 168 store i32 %b, ptr %1, align 4 169 %2 = getelementptr i32, ptr %a, i64 5 170 store i32 %c, ptr %2, align 4 171 ret void 172} 173 174define void @sdd(ptr %a, i64 %b, i64%c) { 175; RV32XTHEADMEMPAIR-LABEL: sdd: 176; RV32XTHEADMEMPAIR: # %bb.0: 177; RV32XTHEADMEMPAIR-NEXT: sw a1, 32(a0) 178; RV32XTHEADMEMPAIR-NEXT: sw a2, 36(a0) 179; RV32XTHEADMEMPAIR-NEXT: sw a3, 40(a0) 180; RV32XTHEADMEMPAIR-NEXT: sw a4, 44(a0) 181; RV32XTHEADMEMPAIR-NEXT: ret 182; 183; RV64XTHEADMEMPAIR-LABEL: sdd: 184; RV64XTHEADMEMPAIR: # %bb.0: 185; RV64XTHEADMEMPAIR-NEXT: th.sdd a1, a2, (a0), 2, 4 186; RV64XTHEADMEMPAIR-NEXT: ret 187 %1 = getelementptr i64, ptr %a, i64 4 188 store i64 %b, ptr %1, align 8 189 %2 = getelementptr i64, ptr %a, i64 5 190 store i64 %c, ptr %2, align 8 191 ret void 192} 193 194define void @swd_0(ptr %a, i32 %b, i32%c) { 195; RV32XTHEADMEMPAIR-LABEL: swd_0: 196; RV32XTHEADMEMPAIR: # %bb.0: 197; RV32XTHEADMEMPAIR-NEXT: th.swd a1, a2, (a0), 0, 3 198; RV32XTHEADMEMPAIR-NEXT: ret 199; 200; RV64XTHEADMEMPAIR-LABEL: swd_0: 201; RV64XTHEADMEMPAIR: # %bb.0: 202; RV64XTHEADMEMPAIR-NEXT: th.swd a1, a2, (a0), 0, 3 203; RV64XTHEADMEMPAIR-NEXT: ret 204 %1 = getelementptr i32, ptr %a, i64 0 205 store i32 %b, ptr %1, align 4 206 %2 = getelementptr i32, ptr %a, i64 1 207 store i32 %c, ptr %2, align 4 208 ret void 209} 210 211define void @sdd_0(ptr %a, i64 %b, i64%c) { 212; RV32XTHEADMEMPAIR-LABEL: sdd_0: 213; RV32XTHEADMEMPAIR: # %bb.0: 214; RV32XTHEADMEMPAIR-NEXT: th.swd a1, a2, (a0), 0, 3 215; RV32XTHEADMEMPAIR-NEXT: th.swd a3, a4, (a0), 1, 3 216; RV32XTHEADMEMPAIR-NEXT: ret 217; 218; RV64XTHEADMEMPAIR-LABEL: sdd_0: 219; RV64XTHEADMEMPAIR: # %bb.0: 220; RV64XTHEADMEMPAIR-NEXT: th.sdd a1, a2, (a0), 0, 4 221; RV64XTHEADMEMPAIR-NEXT: ret 222 %1 = getelementptr i64, ptr %a, i64 0 223 store i64 %b, ptr %1, align 8 224 %2 = getelementptr i64, ptr %a, i64 1 225 store i64 %c, ptr %2, align 8 226 ret void 227} 228 229define i64 @ld64(ptr %a) { 230; RV32XTHEADMEMPAIR-LABEL: ld64: 231; RV32XTHEADMEMPAIR: # %bb.0: 232; RV32XTHEADMEMPAIR-NEXT: th.lwd a2, a1, (a0), 0, 3 233; RV32XTHEADMEMPAIR-NEXT: mv a0, a2 234; RV32XTHEADMEMPAIR-NEXT: ret 235; 236; RV64XTHEADMEMPAIR-LABEL: ld64: 237; RV64XTHEADMEMPAIR: # %bb.0: 238; RV64XTHEADMEMPAIR-NEXT: ld a0, 0(a0) 239; RV64XTHEADMEMPAIR-NEXT: ret 240 %1 = getelementptr i64, ptr %a, i64 0 241 %2 = load i64, ptr %1, align 8 242 ret i64 %2 243} 244 245define i128 @ld128(ptr %a) { 246; RV32XTHEADMEMPAIR-LABEL: ld128: 247; RV32XTHEADMEMPAIR: # %bb.0: 248; RV32XTHEADMEMPAIR-NEXT: th.lwd a2, a3, (a1), 1, 3 249; RV32XTHEADMEMPAIR-NEXT: th.lwd a4, a5, (a1), 0, 3 250; RV32XTHEADMEMPAIR-NEXT: th.swd a2, a3, (a0), 1, 3 251; RV32XTHEADMEMPAIR-NEXT: th.swd a4, a5, (a0), 0, 3 252; RV32XTHEADMEMPAIR-NEXT: ret 253; 254; RV64XTHEADMEMPAIR-LABEL: ld128: 255; RV64XTHEADMEMPAIR: # %bb.0: 256; RV64XTHEADMEMPAIR-NEXT: th.ldd a2, a1, (a0), 0, 4 257; RV64XTHEADMEMPAIR-NEXT: mv a0, a2 258; RV64XTHEADMEMPAIR-NEXT: ret 259 %1 = getelementptr i128, ptr %a, i64 0 260 %2 = load i128, ptr %1, align 8 261 ret i128 %2 262} 263 264define void @sd64(ptr %a, i64 %b) { 265; RV32XTHEADMEMPAIR-LABEL: sd64: 266; RV32XTHEADMEMPAIR: # %bb.0: 267; RV32XTHEADMEMPAIR-NEXT: th.swd a1, a2, (a0), 0, 3 268; RV32XTHEADMEMPAIR-NEXT: ret 269; 270; RV64XTHEADMEMPAIR-LABEL: sd64: 271; RV64XTHEADMEMPAIR: # %bb.0: 272; RV64XTHEADMEMPAIR-NEXT: sd a1, 0(a0) 273; RV64XTHEADMEMPAIR-NEXT: ret 274 %1 = getelementptr i64, ptr %a, i64 0 275 store i64 %b, ptr %1, align 8 276 ret void 277} 278 279define void @sd128(ptr %a, i128 %b) { 280; RV32XTHEADMEMPAIR-LABEL: sd128: 281; RV32XTHEADMEMPAIR: # %bb.0: 282; RV32XTHEADMEMPAIR-NEXT: th.lwd a2, a3, (a1), 1, 3 283; RV32XTHEADMEMPAIR-NEXT: th.lwd a4, a5, (a1), 0, 3 284; RV32XTHEADMEMPAIR-NEXT: th.swd a2, a3, (a0), 1, 3 285; RV32XTHEADMEMPAIR-NEXT: th.swd a4, a5, (a0), 0, 3 286; RV32XTHEADMEMPAIR-NEXT: ret 287; 288; RV64XTHEADMEMPAIR-LABEL: sd128: 289; RV64XTHEADMEMPAIR: # %bb.0: 290; RV64XTHEADMEMPAIR-NEXT: th.sdd a1, a2, (a0), 0, 4 291; RV64XTHEADMEMPAIR-NEXT: ret 292 %1 = getelementptr i128, ptr %a, i64 0 293 store i128 %b, ptr %1, align 8 294 ret void 295} 296 297define i32 @lh(ptr %a) { 298; RV32XTHEADMEMPAIR-LABEL: lh: 299; RV32XTHEADMEMPAIR: # %bb.0: 300; RV32XTHEADMEMPAIR-NEXT: lh a1, 0(a0) 301; RV32XTHEADMEMPAIR-NEXT: lh a0, 2(a0) 302; RV32XTHEADMEMPAIR-NEXT: add a0, a1, a0 303; RV32XTHEADMEMPAIR-NEXT: ret 304; 305; RV64XTHEADMEMPAIR-LABEL: lh: 306; RV64XTHEADMEMPAIR: # %bb.0: 307; RV64XTHEADMEMPAIR-NEXT: lh a1, 0(a0) 308; RV64XTHEADMEMPAIR-NEXT: lh a0, 2(a0) 309; RV64XTHEADMEMPAIR-NEXT: add a0, a1, a0 310; RV64XTHEADMEMPAIR-NEXT: ret 311 %1 = getelementptr i16, ptr %a, i64 0 312 %2 = load i16, ptr %1, align 4 313 %3 = getelementptr i16, ptr %a, i64 1 314 %4 = load i16, ptr %3, align 4 315 %5 = sext i16 %2 to i32 316 %6 = sext i16 %4 to i32 317 %7 = add i32 %5, %6 318 ret i32 %7 319} 320 321define i32 @lb(ptr %a) { 322; RV32XTHEADMEMPAIR-LABEL: lb: 323; RV32XTHEADMEMPAIR: # %bb.0: 324; RV32XTHEADMEMPAIR-NEXT: lb a1, 0(a0) 325; RV32XTHEADMEMPAIR-NEXT: lb a0, 1(a0) 326; RV32XTHEADMEMPAIR-NEXT: add a0, a1, a0 327; RV32XTHEADMEMPAIR-NEXT: ret 328; 329; RV64XTHEADMEMPAIR-LABEL: lb: 330; RV64XTHEADMEMPAIR: # %bb.0: 331; RV64XTHEADMEMPAIR-NEXT: lb a1, 0(a0) 332; RV64XTHEADMEMPAIR-NEXT: lb a0, 1(a0) 333; RV64XTHEADMEMPAIR-NEXT: add a0, a1, a0 334; RV64XTHEADMEMPAIR-NEXT: ret 335 %1 = getelementptr i8, ptr %a, i64 0 336 %2 = load i8, ptr %1, align 4 337 %3 = getelementptr i8, ptr %a, i64 1 338 %4 = load i8, ptr %3, align 4 339 %5 = sext i8 %2 to i32 340 %6 = sext i8 %4 to i32 341 %7 = add i32 %5, %6 342 ret i32 %7 343} 344