blob: 7d8b8d29aa3c9d17dc5c5e7c150bd6d94707fb95 [file] [log] [blame] [edit]
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
; RUN: sed 's/iXLen/i32/g' %s | llc -mtriple=riscv32 | FileCheck %s --check-prefixes=CHECK,RV32I
; RUN: sed 's/iXLen/i64/g' %s | llc -mtriple=riscv64 | FileCheck %s --check-prefixes=CHECK,RV64I
; RUN: sed 's/iXLen/i32/g' %s | llc -mtriple=riscv32 -mattr=+zba | FileCheck %s --check-prefixes=ZBA,RV32ZBA
; RUN: sed 's/iXLen/i64/g' %s | llc -mtriple=riscv64 -mattr=+zba | FileCheck %s --check-prefixes=ZBA,RV64ZBA
define i64 @test_sh3add(ptr %p, iXLen %x, iXLen %y) {
; RV32I-LABEL: test_sh3add:
; RV32I: # %bb.0: # %entry
; RV32I-NEXT: slli a1, a1, 3
; RV32I-NEXT: slli a2, a2, 3
; RV32I-NEXT: add a1, a1, a0
; RV32I-NEXT: add a0, a0, a2
; RV32I-NEXT: lw a2, 480(a1)
; RV32I-NEXT: lw a1, 484(a1)
; RV32I-NEXT: lw a3, 404(a0)
; RV32I-NEXT: lw a4, 400(a0)
; RV32I-NEXT: add a1, a3, a1
; RV32I-NEXT: add a0, a4, a2
; RV32I-NEXT: sltu a2, a0, a4
; RV32I-NEXT: add a1, a1, a2
; RV32I-NEXT: ret
;
; RV64I-LABEL: test_sh3add:
; RV64I: # %bb.0: # %entry
; RV64I-NEXT: slli a1, a1, 3
; RV64I-NEXT: slli a2, a2, 3
; RV64I-NEXT: add a1, a1, a0
; RV64I-NEXT: add a0, a0, a2
; RV64I-NEXT: ld a1, 480(a1)
; RV64I-NEXT: ld a0, 400(a0)
; RV64I-NEXT: add a0, a0, a1
; RV64I-NEXT: ret
;
; RV32ZBA-LABEL: test_sh3add:
; RV32ZBA: # %bb.0: # %entry
; RV32ZBA-NEXT: sh3add a1, a1, a0
; RV32ZBA-NEXT: sh3add a0, a2, a0
; RV32ZBA-NEXT: lw a2, 480(a1)
; RV32ZBA-NEXT: lw a1, 484(a1)
; RV32ZBA-NEXT: lw a3, 404(a0)
; RV32ZBA-NEXT: lw a4, 400(a0)
; RV32ZBA-NEXT: add a1, a3, a1
; RV32ZBA-NEXT: add a0, a4, a2
; RV32ZBA-NEXT: sltu a2, a0, a4
; RV32ZBA-NEXT: add a1, a1, a2
; RV32ZBA-NEXT: ret
;
; RV64ZBA-LABEL: test_sh3add:
; RV64ZBA: # %bb.0: # %entry
; RV64ZBA-NEXT: sh3add a1, a1, a0
; RV64ZBA-NEXT: sh3add a0, a2, a0
; RV64ZBA-NEXT: ld a1, 480(a1)
; RV64ZBA-NEXT: ld a0, 400(a0)
; RV64ZBA-NEXT: add a0, a0, a1
; RV64ZBA-NEXT: ret
entry:
%b = getelementptr inbounds nuw i8, ptr %p, i64 400
%add = add iXLen %x, 10
%arrayidx = getelementptr inbounds nuw [100 x i64], ptr %b, i64 0, iXLen %add
%0 = load i64, ptr %arrayidx, align 8
%arrayidx2 = getelementptr inbounds nuw [100 x i64], ptr %b, i64 0, iXLen %y
%1 = load i64, ptr %arrayidx2, align 8
%add3 = add nsw i64 %1, %0
ret i64 %add3
}
define signext i32 @test_sh2add(ptr %p, iXLen %x, iXLen %y) {
; RV32I-LABEL: test_sh2add:
; RV32I: # %bb.0: # %entry
; RV32I-NEXT: slli a1, a1, 2
; RV32I-NEXT: slli a2, a2, 2
; RV32I-NEXT: add a1, a0, a1
; RV32I-NEXT: add a0, a2, a0
; RV32I-NEXT: lw a1, 1200(a1)
; RV32I-NEXT: lw a0, 1240(a0)
; RV32I-NEXT: add a0, a0, a1
; RV32I-NEXT: ret
;
; RV64I-LABEL: test_sh2add:
; RV64I: # %bb.0: # %entry
; RV64I-NEXT: slli a1, a1, 2
; RV64I-NEXT: slli a2, a2, 2
; RV64I-NEXT: add a1, a0, a1
; RV64I-NEXT: add a0, a2, a0
; RV64I-NEXT: lw a1, 1200(a1)
; RV64I-NEXT: lw a0, 1240(a0)
; RV64I-NEXT: addw a0, a0, a1
; RV64I-NEXT: ret
;
; RV32ZBA-LABEL: test_sh2add:
; RV32ZBA: # %bb.0: # %entry
; RV32ZBA-NEXT: sh2add a1, a1, a0
; RV32ZBA-NEXT: sh2add a0, a2, a0
; RV32ZBA-NEXT: lw a1, 1200(a1)
; RV32ZBA-NEXT: lw a0, 1240(a0)
; RV32ZBA-NEXT: add a0, a0, a1
; RV32ZBA-NEXT: ret
;
; RV64ZBA-LABEL: test_sh2add:
; RV64ZBA: # %bb.0: # %entry
; RV64ZBA-NEXT: sh2add a1, a1, a0
; RV64ZBA-NEXT: sh2add a0, a2, a0
; RV64ZBA-NEXT: lw a1, 1200(a1)
; RV64ZBA-NEXT: lw a0, 1240(a0)
; RV64ZBA-NEXT: addw a0, a0, a1
; RV64ZBA-NEXT: ret
entry:
%c = getelementptr inbounds nuw i8, ptr %p, i64 1200
%arrayidx = getelementptr inbounds nuw [100 x i32], ptr %c, i64 0, iXLen %x
%0 = load i32, ptr %arrayidx, align 4
%add = add iXLen %y, 10
%arrayidx2 = getelementptr inbounds nuw [100 x i32], ptr %c, i64 0, iXLen %add
%1 = load i32, ptr %arrayidx2, align 4
%add3 = add nsw i32 %1, %0
ret i32 %add3
}
define signext i16 @test_sh1add(ptr %p, iXLen %x, iXLen %y) {
; RV32I-LABEL: test_sh1add:
; RV32I: # %bb.0: # %entry
; RV32I-NEXT: slli a1, a1, 1
; RV32I-NEXT: slli a2, a2, 1
; RV32I-NEXT: add a1, a0, a1
; RV32I-NEXT: add a0, a2, a0
; RV32I-NEXT: lh a1, 1600(a1)
; RV32I-NEXT: lh a0, 1620(a0)
; RV32I-NEXT: add a0, a0, a1
; RV32I-NEXT: slli a0, a0, 16
; RV32I-NEXT: srai a0, a0, 16
; RV32I-NEXT: ret
;
; RV64I-LABEL: test_sh1add:
; RV64I: # %bb.0: # %entry
; RV64I-NEXT: slli a1, a1, 1
; RV64I-NEXT: slli a2, a2, 1
; RV64I-NEXT: add a1, a0, a1
; RV64I-NEXT: add a0, a2, a0
; RV64I-NEXT: lh a1, 1600(a1)
; RV64I-NEXT: lh a0, 1620(a0)
; RV64I-NEXT: add a0, a0, a1
; RV64I-NEXT: slli a0, a0, 48
; RV64I-NEXT: srai a0, a0, 48
; RV64I-NEXT: ret
;
; RV32ZBA-LABEL: test_sh1add:
; RV32ZBA: # %bb.0: # %entry
; RV32ZBA-NEXT: sh1add a1, a1, a0
; RV32ZBA-NEXT: sh1add a0, a2, a0
; RV32ZBA-NEXT: lh a1, 1600(a1)
; RV32ZBA-NEXT: lh a0, 1620(a0)
; RV32ZBA-NEXT: add a0, a0, a1
; RV32ZBA-NEXT: slli a0, a0, 16
; RV32ZBA-NEXT: srai a0, a0, 16
; RV32ZBA-NEXT: ret
;
; RV64ZBA-LABEL: test_sh1add:
; RV64ZBA: # %bb.0: # %entry
; RV64ZBA-NEXT: sh1add a1, a1, a0
; RV64ZBA-NEXT: sh1add a0, a2, a0
; RV64ZBA-NEXT: lh a1, 1600(a1)
; RV64ZBA-NEXT: lh a0, 1620(a0)
; RV64ZBA-NEXT: add a0, a0, a1
; RV64ZBA-NEXT: slli a0, a0, 48
; RV64ZBA-NEXT: srai a0, a0, 48
; RV64ZBA-NEXT: ret
entry:
%d = getelementptr inbounds nuw i8, ptr %p, i64 1600
%arrayidx = getelementptr inbounds nuw [100 x i16], ptr %d, i64 0, iXLen %x
%0 = load i16, ptr %arrayidx, align 2
%add = add iXLen %y, 10
%arrayidx2 = getelementptr inbounds nuw [100 x i16], ptr %d, i64 0, iXLen %add
%1 = load i16, ptr %arrayidx2, align 2
%add4 = add i16 %1, %0
ret i16 %add4
}
define zeroext i8 @test_add(ptr %p, iXLen %x, iXLen %y) {
; CHECK-LABEL: test_add:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: add a1, a0, a1
; CHECK-NEXT: add a0, a2, a0
; CHECK-NEXT: lbu a1, 1800(a1)
; CHECK-NEXT: lbu a0, 1810(a0)
; CHECK-NEXT: add a0, a0, a1
; CHECK-NEXT: zext.b a0, a0
; CHECK-NEXT: ret
;
; ZBA-LABEL: test_add:
; ZBA: # %bb.0: # %entry
; ZBA-NEXT: add a1, a0, a1
; ZBA-NEXT: add a0, a2, a0
; ZBA-NEXT: lbu a1, 1800(a1)
; ZBA-NEXT: lbu a0, 1810(a0)
; ZBA-NEXT: add a0, a0, a1
; ZBA-NEXT: zext.b a0, a0
; ZBA-NEXT: ret
entry:
%e = getelementptr inbounds nuw i8, ptr %p, i64 1800
%arrayidx = getelementptr inbounds nuw [1000 x i8], ptr %e, i64 0, iXLen %x
%0 = load i8, ptr %arrayidx, align 1
%add = add iXLen %y, 10
%arrayidx2 = getelementptr inbounds nuw [1000 x i8], ptr %e, i64 0, iXLen %add
%1 = load i8, ptr %arrayidx2, align 1
%add4 = add i8 %1, %0
ret i8 %add4
}
define i64 @test_sh3add_uw(ptr %p, i32 signext %x, i32 signext %y) {
; RV32I-LABEL: test_sh3add_uw:
; RV32I: # %bb.0: # %entry
; RV32I-NEXT: slli a1, a1, 3
; RV32I-NEXT: slli a2, a2, 3
; RV32I-NEXT: add a1, a0, a1
; RV32I-NEXT: add a0, a0, a2
; RV32I-NEXT: lw a2, 404(a0)
; RV32I-NEXT: lw a3, 400(a1)
; RV32I-NEXT: lw a1, 404(a1)
; RV32I-NEXT: lw a4, 400(a0)
; RV32I-NEXT: add a1, a2, a1
; RV32I-NEXT: add a0, a4, a3
; RV32I-NEXT: sltu a2, a0, a4
; RV32I-NEXT: add a1, a1, a2
; RV32I-NEXT: ret
;
; RV64I-LABEL: test_sh3add_uw:
; RV64I: # %bb.0: # %entry
; RV64I-NEXT: slli a1, a1, 32
; RV64I-NEXT: slli a2, a2, 32
; RV64I-NEXT: srli a1, a1, 29
; RV64I-NEXT: srli a2, a2, 29
; RV64I-NEXT: add a1, a0, a1
; RV64I-NEXT: add a0, a0, a2
; RV64I-NEXT: ld a1, 400(a1)
; RV64I-NEXT: ld a0, 400(a0)
; RV64I-NEXT: add a0, a0, a1
; RV64I-NEXT: ret
;
; RV32ZBA-LABEL: test_sh3add_uw:
; RV32ZBA: # %bb.0: # %entry
; RV32ZBA-NEXT: sh3add a1, a1, a0
; RV32ZBA-NEXT: sh3add a0, a2, a0
; RV32ZBA-NEXT: lw a2, 404(a0)
; RV32ZBA-NEXT: lw a3, 400(a1)
; RV32ZBA-NEXT: lw a1, 404(a1)
; RV32ZBA-NEXT: lw a4, 400(a0)
; RV32ZBA-NEXT: add a1, a2, a1
; RV32ZBA-NEXT: add a0, a4, a3
; RV32ZBA-NEXT: sltu a2, a0, a4
; RV32ZBA-NEXT: add a1, a1, a2
; RV32ZBA-NEXT: ret
;
; RV64ZBA-LABEL: test_sh3add_uw:
; RV64ZBA: # %bb.0: # %entry
; RV64ZBA-NEXT: sh3add.uw a1, a1, a0
; RV64ZBA-NEXT: sh3add.uw a0, a2, a0
; RV64ZBA-NEXT: ld a1, 400(a1)
; RV64ZBA-NEXT: ld a0, 400(a0)
; RV64ZBA-NEXT: add a0, a0, a1
; RV64ZBA-NEXT: ret
entry:
%b = getelementptr inbounds nuw i8, ptr %p, i64 400
%idxprom = zext i32 %x to i64
%arrayidx = getelementptr inbounds nuw [100 x i64], ptr %b, i64 0, i64 %idxprom
%0 = load i64, ptr %arrayidx, align 8
%idxprom2 = zext i32 %y to i64
%arrayidx3 = getelementptr inbounds nuw [100 x i64], ptr %b, i64 0, i64 %idxprom2
%1 = load i64, ptr %arrayidx3, align 8
%add4 = add nsw i64 %1, %0
ret i64 %add4
}
define signext i32 @test_sh2add_uw(ptr %p, i32 signext %x, i32 signext %y) {
; RV32I-LABEL: test_sh2add_uw:
; RV32I: # %bb.0: # %entry
; RV32I-NEXT: slli a1, a1, 2
; RV32I-NEXT: slli a2, a2, 2
; RV32I-NEXT: add a1, a0, a1
; RV32I-NEXT: add a0, a0, a2
; RV32I-NEXT: lw a1, 1200(a1)
; RV32I-NEXT: lw a0, 1200(a0)
; RV32I-NEXT: add a0, a0, a1
; RV32I-NEXT: ret
;
; RV64I-LABEL: test_sh2add_uw:
; RV64I: # %bb.0: # %entry
; RV64I-NEXT: slli a1, a1, 32
; RV64I-NEXT: slli a2, a2, 32
; RV64I-NEXT: srli a1, a1, 30
; RV64I-NEXT: srli a2, a2, 30
; RV64I-NEXT: add a1, a0, a1
; RV64I-NEXT: add a0, a0, a2
; RV64I-NEXT: lw a1, 1200(a1)
; RV64I-NEXT: lw a0, 1200(a0)
; RV64I-NEXT: addw a0, a0, a1
; RV64I-NEXT: ret
;
; RV32ZBA-LABEL: test_sh2add_uw:
; RV32ZBA: # %bb.0: # %entry
; RV32ZBA-NEXT: sh2add a1, a1, a0
; RV32ZBA-NEXT: sh2add a0, a2, a0
; RV32ZBA-NEXT: lw a1, 1200(a1)
; RV32ZBA-NEXT: lw a0, 1200(a0)
; RV32ZBA-NEXT: add a0, a0, a1
; RV32ZBA-NEXT: ret
;
; RV64ZBA-LABEL: test_sh2add_uw:
; RV64ZBA: # %bb.0: # %entry
; RV64ZBA-NEXT: sh2add.uw a1, a1, a0
; RV64ZBA-NEXT: sh2add.uw a0, a2, a0
; RV64ZBA-NEXT: lw a1, 1200(a1)
; RV64ZBA-NEXT: lw a0, 1200(a0)
; RV64ZBA-NEXT: addw a0, a0, a1
; RV64ZBA-NEXT: ret
entry:
%c = getelementptr inbounds nuw i8, ptr %p, i64 1200
%idxprom = zext i32 %x to i64
%arrayidx = getelementptr inbounds nuw [100 x i32], ptr %c, i64 0, i64 %idxprom
%0 = load i32, ptr %arrayidx, align 4
%idxprom2 = zext i32 %y to i64
%arrayidx3 = getelementptr inbounds nuw [100 x i32], ptr %c, i64 0, i64 %idxprom2
%1 = load i32, ptr %arrayidx3, align 4
%add4 = add nsw i32 %1, %0
ret i32 %add4
}
define signext i16 @test_sh1add_uw(ptr %p, i32 signext %x, i32 signext %y) {
; RV32I-LABEL: test_sh1add_uw:
; RV32I: # %bb.0: # %entry
; RV32I-NEXT: slli a1, a1, 1
; RV32I-NEXT: slli a2, a2, 1
; RV32I-NEXT: add a1, a0, a1
; RV32I-NEXT: add a0, a2, a0
; RV32I-NEXT: lh a1, 1600(a1)
; RV32I-NEXT: lh a0, 1620(a0)
; RV32I-NEXT: add a0, a0, a1
; RV32I-NEXT: slli a0, a0, 16
; RV32I-NEXT: srai a0, a0, 16
; RV32I-NEXT: ret
;
; RV64I-LABEL: test_sh1add_uw:
; RV64I: # %bb.0: # %entry
; RV64I-NEXT: slli a1, a1, 32
; RV64I-NEXT: addi a2, a2, 10
; RV64I-NEXT: srli a1, a1, 31
; RV64I-NEXT: slli a2, a2, 32
; RV64I-NEXT: add a1, a0, a1
; RV64I-NEXT: srli a2, a2, 31
; RV64I-NEXT: add a0, a0, a2
; RV64I-NEXT: lh a1, 1600(a1)
; RV64I-NEXT: lh a0, 1600(a0)
; RV64I-NEXT: add a0, a0, a1
; RV64I-NEXT: slli a0, a0, 48
; RV64I-NEXT: srai a0, a0, 48
; RV64I-NEXT: ret
;
; RV32ZBA-LABEL: test_sh1add_uw:
; RV32ZBA: # %bb.0: # %entry
; RV32ZBA-NEXT: sh1add a1, a1, a0
; RV32ZBA-NEXT: sh1add a0, a2, a0
; RV32ZBA-NEXT: lh a1, 1600(a1)
; RV32ZBA-NEXT: lh a0, 1620(a0)
; RV32ZBA-NEXT: add a0, a0, a1
; RV32ZBA-NEXT: slli a0, a0, 16
; RV32ZBA-NEXT: srai a0, a0, 16
; RV32ZBA-NEXT: ret
;
; RV64ZBA-LABEL: test_sh1add_uw:
; RV64ZBA: # %bb.0: # %entry
; RV64ZBA-NEXT: sh1add.uw a1, a1, a0
; RV64ZBA-NEXT: addi a2, a2, 10
; RV64ZBA-NEXT: sh1add.uw a0, a2, a0
; RV64ZBA-NEXT: lh a1, 1600(a1)
; RV64ZBA-NEXT: lh a0, 1600(a0)
; RV64ZBA-NEXT: add a0, a0, a1
; RV64ZBA-NEXT: slli a0, a0, 48
; RV64ZBA-NEXT: srai a0, a0, 48
; RV64ZBA-NEXT: ret
entry:
%d = getelementptr inbounds nuw i8, ptr %p, i64 1600
%idxprom = zext i32 %x to i64
%arrayidx = getelementptr inbounds nuw [100 x i16], ptr %d, i64 0, i64 %idxprom
%0 = load i16, ptr %arrayidx, align 2
%add = add i32 %y, 10
%idxprom2 = zext i32 %add to i64
%arrayidx3 = getelementptr inbounds nuw [100 x i16], ptr %d, i64 0, i64 %idxprom2
%1 = load i16, ptr %arrayidx3, align 2
%add5 = add i16 %1, %0
ret i16 %add5
}
define zeroext i8 @test_add_uw(ptr %p, i32 signext %x, i32 signext %y) {
; RV32I-LABEL: test_add_uw:
; RV32I: # %bb.0: # %entry
; RV32I-NEXT: add a1, a0, a1
; RV32I-NEXT: add a0, a0, a2
; RV32I-NEXT: lbu a1, 1800(a1)
; RV32I-NEXT: lbu a0, 1800(a0)
; RV32I-NEXT: add a0, a0, a1
; RV32I-NEXT: zext.b a0, a0
; RV32I-NEXT: ret
;
; RV64I-LABEL: test_add_uw:
; RV64I: # %bb.0: # %entry
; RV64I-NEXT: slli a1, a1, 32
; RV64I-NEXT: slli a2, a2, 32
; RV64I-NEXT: srli a1, a1, 32
; RV64I-NEXT: srli a2, a2, 32
; RV64I-NEXT: add a1, a0, a1
; RV64I-NEXT: add a0, a0, a2
; RV64I-NEXT: lbu a1, 1800(a1)
; RV64I-NEXT: lbu a0, 1800(a0)
; RV64I-NEXT: add a0, a0, a1
; RV64I-NEXT: zext.b a0, a0
; RV64I-NEXT: ret
;
; RV32ZBA-LABEL: test_add_uw:
; RV32ZBA: # %bb.0: # %entry
; RV32ZBA-NEXT: add a1, a0, a1
; RV32ZBA-NEXT: add a0, a0, a2
; RV32ZBA-NEXT: lbu a1, 1800(a1)
; RV32ZBA-NEXT: lbu a0, 1800(a0)
; RV32ZBA-NEXT: add a0, a0, a1
; RV32ZBA-NEXT: zext.b a0, a0
; RV32ZBA-NEXT: ret
;
; RV64ZBA-LABEL: test_add_uw:
; RV64ZBA: # %bb.0: # %entry
; RV64ZBA-NEXT: add.uw a1, a1, a0
; RV64ZBA-NEXT: add.uw a0, a2, a0
; RV64ZBA-NEXT: lbu a1, 1800(a1)
; RV64ZBA-NEXT: lbu a0, 1800(a0)
; RV64ZBA-NEXT: add a0, a0, a1
; RV64ZBA-NEXT: zext.b a0, a0
; RV64ZBA-NEXT: ret
entry:
%e = getelementptr inbounds nuw i8, ptr %p, i64 1800
%idxprom = zext i32 %x to i64
%arrayidx = getelementptr inbounds nuw [1000 x i8], ptr %e, i64 0, i64 %idxprom
%0 = load i8, ptr %arrayidx, align 1
%idxprom2 = zext i32 %y to i64
%arrayidx3 = getelementptr inbounds nuw [1000 x i8], ptr %e, i64 0, i64 %idxprom2
%1 = load i8, ptr %arrayidx3, align 1
%add5 = add i8 %1, %0
ret i8 %add5
}
; The addi is part of the index and used with 2 different scales.
define signext i32 @test_scaled_index_addi(ptr %p, iXLen %x) {
; RV32I-LABEL: test_scaled_index_addi:
; RV32I: # %bb.0: # %entry
; RV32I-NEXT: slli a2, a1, 2
; RV32I-NEXT: slli a1, a1, 1
; RV32I-NEXT: add a2, a0, a2
; RV32I-NEXT: add a0, a0, a1
; RV32I-NEXT: lw a1, 1196(a2)
; RV32I-NEXT: lh a0, 1598(a0)
; RV32I-NEXT: add a0, a1, a0
; RV32I-NEXT: ret
;
; RV64I-LABEL: test_scaled_index_addi:
; RV64I: # %bb.0: # %entry
; RV64I-NEXT: slli a2, a1, 2
; RV64I-NEXT: slli a1, a1, 1
; RV64I-NEXT: add a2, a0, a2
; RV64I-NEXT: add a0, a0, a1
; RV64I-NEXT: lw a1, 1196(a2)
; RV64I-NEXT: lh a0, 1598(a0)
; RV64I-NEXT: addw a0, a1, a0
; RV64I-NEXT: ret
;
; RV32ZBA-LABEL: test_scaled_index_addi:
; RV32ZBA: # %bb.0: # %entry
; RV32ZBA-NEXT: sh2add a2, a1, a0
; RV32ZBA-NEXT: sh1add a0, a1, a0
; RV32ZBA-NEXT: lw a1, 1196(a2)
; RV32ZBA-NEXT: lh a0, 1598(a0)
; RV32ZBA-NEXT: add a0, a1, a0
; RV32ZBA-NEXT: ret
;
; RV64ZBA-LABEL: test_scaled_index_addi:
; RV64ZBA: # %bb.0: # %entry
; RV64ZBA-NEXT: sh2add a2, a1, a0
; RV64ZBA-NEXT: sh1add a0, a1, a0
; RV64ZBA-NEXT: lw a1, 1196(a2)
; RV64ZBA-NEXT: lh a0, 1598(a0)
; RV64ZBA-NEXT: addw a0, a1, a0
; RV64ZBA-NEXT: ret
entry:
%c = getelementptr inbounds nuw i8, ptr %p, i64 1200
%sub = add iXLen %x, -1
%arrayidx = getelementptr inbounds nuw [100 x i32], ptr %c, i64 0, iXLen %sub
%0 = load i32, ptr %arrayidx, align 4
%d = getelementptr inbounds nuw i8, ptr %p, i64 1600
%arrayidx2 = getelementptr inbounds nuw [100 x i16], ptr %d, i64 0, iXLen %sub
%1 = load i16, ptr %arrayidx2, align 2
%conv = sext i16 %1 to i32
%add = add nsw i32 %0, %conv
ret i32 %add
}
; Offset is a pair of addis. We can fold one of them.
define signext i32 @test_medium_offset(ptr %p, iXLen %x, iXLen %y) {
; RV32I-LABEL: test_medium_offset:
; RV32I: # %bb.0: # %entry
; RV32I-NEXT: addi a0, a0, 2047
; RV32I-NEXT: slli a1, a1, 2
; RV32I-NEXT: slli a2, a2, 2
; RV32I-NEXT: add a1, a0, a1
; RV32I-NEXT: add a0, a2, a0
; RV32I-NEXT: lw a1, 753(a1)
; RV32I-NEXT: lw a0, 793(a0)
; RV32I-NEXT: add a0, a0, a1
; RV32I-NEXT: ret
;
; RV64I-LABEL: test_medium_offset:
; RV64I: # %bb.0: # %entry
; RV64I-NEXT: addi a0, a0, 2047
; RV64I-NEXT: slli a1, a1, 2
; RV64I-NEXT: slli a2, a2, 2
; RV64I-NEXT: add a1, a0, a1
; RV64I-NEXT: add a0, a2, a0
; RV64I-NEXT: lw a1, 753(a1)
; RV64I-NEXT: lw a0, 793(a0)
; RV64I-NEXT: addw a0, a0, a1
; RV64I-NEXT: ret
;
; RV32ZBA-LABEL: test_medium_offset:
; RV32ZBA: # %bb.0: # %entry
; RV32ZBA-NEXT: addi a0, a0, 2047
; RV32ZBA-NEXT: sh2add a1, a1, a0
; RV32ZBA-NEXT: sh2add a0, a2, a0
; RV32ZBA-NEXT: lw a1, 753(a1)
; RV32ZBA-NEXT: lw a0, 793(a0)
; RV32ZBA-NEXT: add a0, a0, a1
; RV32ZBA-NEXT: ret
;
; RV64ZBA-LABEL: test_medium_offset:
; RV64ZBA: # %bb.0: # %entry
; RV64ZBA-NEXT: addi a0, a0, 2047
; RV64ZBA-NEXT: sh2add a1, a1, a0
; RV64ZBA-NEXT: sh2add a0, a2, a0
; RV64ZBA-NEXT: lw a1, 753(a1)
; RV64ZBA-NEXT: lw a0, 793(a0)
; RV64ZBA-NEXT: addw a0, a0, a1
; RV64ZBA-NEXT: ret
entry:
%f = getelementptr inbounds nuw i8, ptr %p, i64 2800
%arrayidx = getelementptr inbounds nuw [1000 x i32], ptr %f, i64 0, iXLen %x
%0 = load i32, ptr %arrayidx, align 4
%add = add iXLen %y, 10
%arrayidx2 = getelementptr inbounds nuw [1000 x i32], ptr %f, i64 0, iXLen %add
%1 = load i32, ptr %arrayidx2, align 4
%add3 = add nsw i32 %1, %0
ret i32 %add3
}
; Offset is a lui+addiw. We can't fold this on RV64.
define signext i32 @test_large_offset(ptr %p, iXLen %x, iXLen %y) {
; RV32I-LABEL: test_large_offset:
; RV32I: # %bb.0: # %entry
; RV32I-NEXT: lui a3, 2
; RV32I-NEXT: slli a1, a1, 2
; RV32I-NEXT: slli a2, a2, 2
; RV32I-NEXT: add a0, a0, a3
; RV32I-NEXT: add a1, a0, a1
; RV32I-NEXT: add a0, a2, a0
; RV32I-NEXT: lw a1, -1392(a1)
; RV32I-NEXT: lw a0, -1352(a0)
; RV32I-NEXT: add a0, a0, a1
; RV32I-NEXT: ret
;
; RV64I-LABEL: test_large_offset:
; RV64I: # %bb.0: # %entry
; RV64I-NEXT: lui a3, 2
; RV64I-NEXT: slli a1, a1, 2
; RV64I-NEXT: slli a2, a2, 2
; RV64I-NEXT: addiw a3, a3, -1392
; RV64I-NEXT: add a0, a0, a3
; RV64I-NEXT: add a1, a0, a1
; RV64I-NEXT: add a0, a2, a0
; RV64I-NEXT: lw a1, 0(a1)
; RV64I-NEXT: lw a0, 40(a0)
; RV64I-NEXT: addw a0, a0, a1
; RV64I-NEXT: ret
;
; RV32ZBA-LABEL: test_large_offset:
; RV32ZBA: # %bb.0: # %entry
; RV32ZBA-NEXT: li a3, 1700
; RV32ZBA-NEXT: sh2add a0, a3, a0
; RV32ZBA-NEXT: sh2add a1, a1, a0
; RV32ZBA-NEXT: sh2add a0, a2, a0
; RV32ZBA-NEXT: lw a1, 0(a1)
; RV32ZBA-NEXT: lw a0, 40(a0)
; RV32ZBA-NEXT: add a0, a0, a1
; RV32ZBA-NEXT: ret
;
; RV64ZBA-LABEL: test_large_offset:
; RV64ZBA: # %bb.0: # %entry
; RV64ZBA-NEXT: li a3, 1700
; RV64ZBA-NEXT: sh2add a0, a3, a0
; RV64ZBA-NEXT: sh2add a1, a1, a0
; RV64ZBA-NEXT: sh2add a0, a2, a0
; RV64ZBA-NEXT: lw a1, 0(a1)
; RV64ZBA-NEXT: lw a0, 40(a0)
; RV64ZBA-NEXT: addw a0, a0, a1
; RV64ZBA-NEXT: ret
entry:
%g = getelementptr inbounds nuw i8, ptr %p, i64 6800
%arrayidx = getelementptr inbounds nuw [200 x i32], ptr %g, i64 0, iXLen %x
%0 = load i32, ptr %arrayidx, align 4
%add = add iXLen %y, 10
%arrayidx2 = getelementptr inbounds nuw [200 x i32], ptr %g, i64 0, iXLen %add
%1 = load i32, ptr %arrayidx2, align 4
%add3 = add nsw i32 %1, %0
ret i32 %add3
}
; After folding we can CSE the sh2add
define signext i32 @test_cse(ptr %p, iXLen %x) {
; RV32I-LABEL: test_cse:
; RV32I: # %bb.0: # %entry
; RV32I-NEXT: slli a1, a1, 2
; RV32I-NEXT: add a0, a0, a1
; RV32I-NEXT: lw a1, 1200(a0)
; RV32I-NEXT: addi a0, a0, 2047
; RV32I-NEXT: lw a0, 753(a0)
; RV32I-NEXT: add a0, a0, a1
; RV32I-NEXT: ret
;
; RV64I-LABEL: test_cse:
; RV64I: # %bb.0: # %entry
; RV64I-NEXT: slli a1, a1, 2
; RV64I-NEXT: add a0, a0, a1
; RV64I-NEXT: lw a1, 1200(a0)
; RV64I-NEXT: addi a0, a0, 2047
; RV64I-NEXT: lw a0, 753(a0)
; RV64I-NEXT: addw a0, a0, a1
; RV64I-NEXT: ret
;
; RV32ZBA-LABEL: test_cse:
; RV32ZBA: # %bb.0: # %entry
; RV32ZBA-NEXT: sh2add a0, a1, a0
; RV32ZBA-NEXT: lw a1, 1200(a0)
; RV32ZBA-NEXT: addi a0, a0, 2047
; RV32ZBA-NEXT: lw a0, 753(a0)
; RV32ZBA-NEXT: add a0, a0, a1
; RV32ZBA-NEXT: ret
;
; RV64ZBA-LABEL: test_cse:
; RV64ZBA: # %bb.0: # %entry
; RV64ZBA-NEXT: sh2add a0, a1, a0
; RV64ZBA-NEXT: lw a1, 1200(a0)
; RV64ZBA-NEXT: addi a0, a0, 2047
; RV64ZBA-NEXT: lw a0, 753(a0)
; RV64ZBA-NEXT: addw a0, a0, a1
; RV64ZBA-NEXT: ret
entry:
%c = getelementptr inbounds nuw i8, ptr %p, i64 1200
%arrayidx = getelementptr inbounds nuw [100 x i32], ptr %c, i64 0, iXLen %x
%0 = load i32, ptr %arrayidx, align 4
%f = getelementptr inbounds nuw i8, ptr %p, i64 2800
%arrayidx1 = getelementptr inbounds nuw [1000 x i32], ptr %f, i64 0, iXLen %x
%1 = load i32, ptr %arrayidx1, align 4
%add = add nsw i32 %1, %0
ret i32 %add
}
define zeroext i8 @test_optsize(ptr %p, iXLen %x, iXLen %y) optsize {
; CHECK-LABEL: test_optsize:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: addi a0, a0, 1800
; CHECK-NEXT: add a1, a0, a1
; CHECK-NEXT: add a0, a2, a0
; CHECK-NEXT: lbu a1, 0(a1)
; CHECK-NEXT: lbu a0, 10(a0)
; CHECK-NEXT: add a0, a0, a1
; CHECK-NEXT: zext.b a0, a0
; CHECK-NEXT: ret
;
; ZBA-LABEL: test_optsize:
; ZBA: # %bb.0: # %entry
; ZBA-NEXT: addi a0, a0, 1800
; ZBA-NEXT: add a1, a0, a1
; ZBA-NEXT: add a0, a2, a0
; ZBA-NEXT: lbu a1, 0(a1)
; ZBA-NEXT: lbu a0, 10(a0)
; ZBA-NEXT: add a0, a0, a1
; ZBA-NEXT: zext.b a0, a0
; ZBA-NEXT: ret
entry:
%e = getelementptr inbounds nuw i8, ptr %p, i64 1800
%arrayidx = getelementptr inbounds nuw [1000 x i8], ptr %e, i64 0, iXLen %x
%0 = load i8, ptr %arrayidx, align 1
%add = add iXLen %y, 10
%arrayidx2 = getelementptr inbounds nuw [1000 x i8], ptr %e, i64 0, iXLen %add
%1 = load i8, ptr %arrayidx2, align 1
%add4 = add i8 %1, %0
ret i8 %add4
}
define zeroext i8 @test_minsize(ptr %p, iXLen %x, iXLen %y) minsize {
; CHECK-LABEL: test_minsize:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: addi a0, a0, 1800
; CHECK-NEXT: add a1, a0, a1
; CHECK-NEXT: add a0, a2, a0
; CHECK-NEXT: lbu a1, 0(a1)
; CHECK-NEXT: lbu a0, 10(a0)
; CHECK-NEXT: add a0, a0, a1
; CHECK-NEXT: zext.b a0, a0
; CHECK-NEXT: ret
;
; ZBA-LABEL: test_minsize:
; ZBA: # %bb.0: # %entry
; ZBA-NEXT: addi a0, a0, 1800
; ZBA-NEXT: add a1, a0, a1
; ZBA-NEXT: add a0, a2, a0
; ZBA-NEXT: lbu a1, 0(a1)
; ZBA-NEXT: lbu a0, 10(a0)
; ZBA-NEXT: add a0, a0, a1
; ZBA-NEXT: zext.b a0, a0
; ZBA-NEXT: ret
entry:
%e = getelementptr inbounds nuw i8, ptr %p, i64 1800
%arrayidx = getelementptr inbounds nuw [1000 x i8], ptr %e, i64 0, iXLen %x
%0 = load i8, ptr %arrayidx, align 1
%add = add iXLen %y, 10
%arrayidx2 = getelementptr inbounds nuw [1000 x i8], ptr %e, i64 0, iXLen %add
%1 = load i8, ptr %arrayidx2, align 1
%add4 = add i8 %1, %0
ret i8 %add4
}