diff options
Diffstat (limited to 'llvm/test/CodeGen/RISCV/lpad.ll')
| -rw-r--r-- | llvm/test/CodeGen/RISCV/lpad.ll | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/llvm/test/CodeGen/RISCV/lpad.ll b/llvm/test/CodeGen/RISCV/lpad.ll new file mode 100644 index 000000000000..de82a9ee4e34 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/lpad.ll @@ -0,0 +1,101 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple riscv32 -mattr=+experimental-zicfilp < %s | FileCheck %s --check-prefixes=CHECK,RV32 +; RUN: llc -mtriple riscv64 -mattr=+experimental-zicfilp < %s | FileCheck %s --check-prefixes=CHECK,RV64 + +; Check indirectbr. +@__const.indirctbr.addr = private unnamed_addr constant [2 x ptr] [ptr blockaddress(@indirctbr, %labelA), ptr blockaddress(@indirctbr, %labelB)], align 8 +define void @indirctbr(i32 %i, ptr %p) { +; RV32-LABEL: indirctbr: +; RV32: # %bb.0: # %entry +; RV32-NEXT: lpad 0 +; RV32-NEXT: slli a0, a0, 2 +; RV32-NEXT: lui a2, %hi(.L__const.indirctbr.addr) +; RV32-NEXT: addi a2, a2, %lo(.L__const.indirctbr.addr) +; RV32-NEXT: add a0, a2, a0 +; RV32-NEXT: lw a0, 0(a0) +; RV32-NEXT: jr a0 +; RV32-NEXT: .p2align 2 +; RV32-NEXT: .Ltmp0: # Block address taken +; RV32-NEXT: .LBB0_1: # %labelA +; RV32-NEXT: lpad 0 +; RV32-NEXT: li a0, 1 +; RV32-NEXT: sw a0, 0(a1) +; RV32-NEXT: .p2align 2 +; RV32-NEXT: .Ltmp1: # Block address taken +; RV32-NEXT: .LBB0_2: # %labelB +; RV32-NEXT: lpad 0 +; RV32-NEXT: li a0, 2 +; RV32-NEXT: sw a0, 0(a1) +; RV32-NEXT: ret +; +; RV64-LABEL: indirctbr: +; RV64: # %bb.0: # %entry +; RV64-NEXT: lpad 0 +; RV64-NEXT: sext.w a0, a0 +; RV64-NEXT: slli a0, a0, 3 +; RV64-NEXT: lui a2, %hi(.L__const.indirctbr.addr) +; RV64-NEXT: addi a2, a2, %lo(.L__const.indirctbr.addr) +; RV64-NEXT: add a0, a2, a0 +; RV64-NEXT: ld a0, 0(a0) +; RV64-NEXT: jr a0 +; RV64-NEXT: .p2align 2 +; RV64-NEXT: .Ltmp0: # Block address taken +; RV64-NEXT: .LBB0_1: # %labelA +; RV64-NEXT: lpad 0 +; RV64-NEXT: li a0, 1 +; RV64-NEXT: sw a0, 0(a1) +; RV64-NEXT: .p2align 2 +; RV64-NEXT: .Ltmp1: # Block address taken +; RV64-NEXT: .LBB0_2: # %labelB +; RV64-NEXT: lpad 0 +; RV64-NEXT: li a0, 2 +; RV64-NEXT: sw a0, 0(a1) +; RV64-NEXT: ret +entry: + %arrayidx = getelementptr inbounds [2 x ptr], ptr @__const.indirctbr.addr, i64 0, i32 %i + %0 = load ptr, ptr %arrayidx + indirectbr ptr %0, [label %labelA, label %labelB] + +labelA: ; preds = %entry + store volatile i32 1, ptr %p + br label %labelB + +labelB: ; preds = %labelA, %entry + store volatile i32 2, ptr %p + ret void +} + +; Check external linkage function. +define void @external() { +; CHECK-LABEL: external: +; CHECK: # %bb.0: +; CHECK-NEXT: lpad 0 +; CHECK-NEXT: ret + ret void +} + +; Check internal linkage function. +define internal void @internal() { +; CHECK-LABEL: internal: +; CHECK: # %bb.0: +; CHECK-NEXT: ret + ret void +} + +; Check internal linkage function with taken address. +@foo = constant ptr @internal2 +define internal void @internal2() { +; CHECK-LABEL: internal2: +; CHECK: # %bb.0: +; CHECK-NEXT: lpad 0 +; CHECK-NEXT: ret + ret void +} + +; Check interrupt function does not need landing pad. +define void @interrupt() "interrupt"="user" { +; CHECK-LABEL: interrupt: +; CHECK: # %bb.0: +; CHECK-NEXT: mret + ret void +} |
