; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6 ; RUN: llc -mtriple=riscv32 -mattr=+xqcili,+xqcisls,+zba,+xqciac -verify-machineinstrs %s -o - | FileCheck %s @sym = external global i8, align 1 define i32 @load_scaled(i32 %idx) nounwind { ; CHECK-LABEL: load_scaled: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: qc.e.li a1, sym+16 ; CHECK-NEXT: qc.lrw a0, a1, a0, 2 ; CHECK-NEXT: ret entry: %baseptr = getelementptr i8, i8* @sym, i32 0 %baseint = ptrtoint i8* %baseptr to i32 %idxsh = shl i32 %idx, 2 %sum = add i32 %baseint, %idxsh %sum_ptr = inttoptr i32 %sum to i8* %addr_plus_imm = getelementptr i8, i8* %sum_ptr, i32 16 %addr_i32p = bitcast i8* %addr_plus_imm to i32* %val = load i32, i32* %addr_i32p, align 4 ret i32 %val } define void @store_scaled(i32 %idx, i32 %val) nounwind { ; CHECK-LABEL: store_scaled: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: qc.e.li a2, sym+12 ; CHECK-NEXT: qc.srw a1, a2, a0, 3 ; CHECK-NEXT: ret entry: %baseptr = getelementptr i8, i8* @sym, i32 0 %baseint = ptrtoint i8* %baseptr to i32 %idxsh = shl i32 %idx, 3 %sum = add i32 %baseint, %idxsh %sum_ptr = inttoptr i32 %sum to i8* %addr_plus_imm = getelementptr i8, i8* %sum_ptr, i32 12 %addr_i32p = bitcast i8* %addr_plus_imm to i32* store i32 %val, i32* %addr_i32p, align 4 ret void } define i32 @load_scaled_i8(i32 %idx) nounwind { ; CHECK-LABEL: load_scaled_i8: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: qc.e.li a1, sym+5 ; CHECK-NEXT: qc.lrb a0, a1, a0, 2 ; CHECK-NEXT: ret entry: %baseptr = getelementptr i8, i8* @sym, i32 0 %baseint = ptrtoint i8* %baseptr to i32 %idxsh = shl i32 %idx, 2 %sum = add i32 %baseint, %idxsh %sum_ptr = inttoptr i32 %sum to i8* %addr_plus_imm = getelementptr i8, i8* %sum_ptr, i32 5 %val8 = load i8, i8* %addr_plus_imm, align 1 %val = sext i8 %val8 to i32 ret i32 %val } define void @store_scaled_i8(i32 %idx, i32 %val) nounwind { ; CHECK-LABEL: store_scaled_i8: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: qc.e.li a2, sym+7 ; CHECK-NEXT: qc.srb a1, a2, a0, 3 ; CHECK-NEXT: ret entry: %baseptr = getelementptr i8, i8* @sym, i32 0 %baseint = ptrtoint i8* %baseptr to i32 %idxsh = shl i32 %idx, 3 %sum = add i32 %baseint, %idxsh %sum_ptr = inttoptr i32 %sum to i8* %addr_plus_imm = getelementptr i8, i8* %sum_ptr, i32 7 %val8 = trunc i32 %val to i8 store i8 %val8, i8* %addr_plus_imm, align 1 ret void } define i32 @load_scaled_i16(i32 %idx) nounwind { ; CHECK-LABEL: load_scaled_i16: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: qc.e.li a1, sym+6 ; CHECK-NEXT: qc.lrh a0, a1, a0, 1 ; CHECK-NEXT: ret entry: %baseptr = getelementptr i8, i8* @sym, i32 0 %baseint = ptrtoint i8* %baseptr to i32 %idxsh = shl i32 %idx, 1 %sum = add i32 %baseint, %idxsh %sum_ptr = inttoptr i32 %sum to i16* %addr_plus_imm = getelementptr i16, i16* %sum_ptr, i32 3 %val16 = load i16, i16* %addr_plus_imm, align 2 %val = sext i16 %val16 to i32 ret i32 %val } define void @store_scaled_i16(i32 %idx, i32 %val) nounwind { ; CHECK-LABEL: store_scaled_i16: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: qc.e.li a2, sym+10 ; CHECK-NEXT: qc.srh a1, a2, a0, 2 ; CHECK-NEXT: ret entry: %baseptr = getelementptr i8, i8* @sym, i32 0 %baseint = ptrtoint i8* %baseptr to i32 %idxsh = shl i32 %idx, 2 %sum = add i32 %baseint, %idxsh %sum_ptr = inttoptr i32 %sum to i16* %addr_plus_imm = getelementptr i16, i16* %sum_ptr, i32 5 %val16 = trunc i32 %val to i16 store i16 %val16, i16* %addr_plus_imm, align 2 ret void } define void @no_store_scaled_i16_multiuse_base_reg(i32 %idx, i32 %val) nounwind { ; CHECK-LABEL: no_store_scaled_i16_multiuse_base_reg: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: qc.e.li a2, sym ; CHECK-NEXT: sh2add a0, a0, a2 ; CHECK-NEXT: sh a1, 10(a0) ; CHECK-NEXT: sh a1, 14(a0) ; CHECK-NEXT: ret entry: %baseptr = getelementptr i8, i8* @sym, i32 0 %baseint = ptrtoint i8* %baseptr to i32 %idxsh = shl i32 %idx, 2 %sum = add i32 %baseint, %idxsh %sum_ptr = inttoptr i32 %sum to i16* %addr_plus_imm = getelementptr i16, i16* %sum_ptr, i32 5 %addr_plus_imm2 = getelementptr i16, i16* %sum_ptr, i32 7 %val16 = trunc i32 %val to i16 store i16 %val16, i16* %addr_plus_imm, align 2 store i16 %val16, i16* %addr_plus_imm2, align 2 ret void } define void @no_store_scaled_i8_multiuse_scaled_reg(i32 %idx, i32 %val) nounwind { ; CHECK-LABEL: no_store_scaled_i8_multiuse_scaled_reg: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: qc.e.li a2, sym ; CHECK-NEXT: sh3add a0, a0, a2 ; CHECK-NEXT: add a0, a0, a1 ; CHECK-NEXT: sb a1, 7(a0) ; CHECK-NEXT: ret entry: %baseptr = getelementptr i8, i8* @sym, i32 0 %baseint = ptrtoint i8* %baseptr to i32 %idxsh = shl i32 %idx, 3 %sum = add i32 %baseint, %idxsh %sum2 = add i32 %sum, %val %sum_ptr = inttoptr i32 %sum2 to i8* %addr_plus_imm = getelementptr i8, i8* %sum_ptr, i32 7 %val8 = trunc i32 %val to i8 store i8 %val8, i8* %addr_plus_imm, align 1 ret void } define i32 @load_scaled_i16_shift_gt_3(i32 %idx) nounwind { ; CHECK-LABEL: load_scaled_i16_shift_gt_3: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: qc.e.li a1, sym+6 ; CHECK-NEXT: qc.lrh a0, a1, a0, 5 ; CHECK-NEXT: ret entry: %baseptr = getelementptr i8, i8* @sym, i32 0 %baseint = ptrtoint i8* %baseptr to i32 %idxsh = shl i32 %idx, 5 %sum = add i32 %baseint, %idxsh %sum_ptr = inttoptr i32 %sum to i16* %addr_plus_imm = getelementptr i16, i16* %sum_ptr, i32 3 %val16 = load i16, i16* %addr_plus_imm, align 2 %val = sext i16 %val16 to i32 ret i32 %val } define i32 @no_load_scaled_i16_shift_gt_7(i32 %idx) nounwind { ; CHECK-LABEL: no_load_scaled_i16_shift_gt_7: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: qc.e.li a1, sym ; CHECK-NEXT: qc.shladd a0, a0, a1, 8 ; CHECK-NEXT: lh a0, 6(a0) ; CHECK-NEXT: ret entry: %baseptr = getelementptr i8, i8* @sym, i32 0 %baseint = ptrtoint i8* %baseptr to i32 %idxsh = shl i32 %idx, 8 %sum = add i32 %baseint, %idxsh %sum_ptr = inttoptr i32 %sum to i16* %addr_plus_imm = getelementptr i16, i16* %sum_ptr, i32 3 %val16 = load i16, i16* %addr_plus_imm, align 2 %val = sext i16 %val16 to i32 ret i32 %val }