The comment shows that at the time we were worried about producing the alias in assembly that might be ingested by a binutils version that doesn't yet support it. binutils gained support over 4 years ago <https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=c2137f55ad04e451d834048d4bfec1de2daea20e>. With all the changes in areas such as ELF attributes, if you tried to use LLVM's RISC-V assembler output with a binutils that old then zext.b would be the least of your worries.
734 lines
23 KiB
LLVM
734 lines
23 KiB
LLVM
; 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
|
|
}
|