1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=riscv32 -mattr=+f -target-abi=ilp32f -code-model=small -verify-machineinstrs < %s \ 3; RUN: | FileCheck %s -check-prefix=RV32I-SMALL 4; RUN: llc -mtriple=riscv32 -mattr=+f -target-abi=ilp32f -code-model=medium -verify-machineinstrs < %s \ 5; RUN: | FileCheck %s -check-prefix=RV32I-MEDIUM 6 7; Check lowering of globals 8@G = global i32 0 9 10define i32 @lower_global(i32 %a) nounwind { 11; RV32I-SMALL-LABEL: lower_global: 12; RV32I-SMALL: # %bb.0: 13; RV32I-SMALL-NEXT: lui a0, %hi(G) 14; RV32I-SMALL-NEXT: lw a0, %lo(G)(a0) 15; RV32I-SMALL-NEXT: ret 16; 17; RV32I-MEDIUM-LABEL: lower_global: 18; RV32I-MEDIUM: # %bb.0: 19; RV32I-MEDIUM-NEXT: .LBB0_1: # Label of block must be emitted 20; RV32I-MEDIUM-NEXT: auipc a0, %pcrel_hi(G) 21; RV32I-MEDIUM-NEXT: addi a0, a0, %pcrel_lo(.LBB0_1) 22; RV32I-MEDIUM-NEXT: lw a0, 0(a0) 23; RV32I-MEDIUM-NEXT: ret 24 %1 = load volatile i32, i32* @G 25 ret i32 %1 26} 27 28; Check lowering of blockaddresses 29 30@addr = global i8* null 31 32define void @lower_blockaddress() nounwind { 33; RV32I-SMALL-LABEL: lower_blockaddress: 34; RV32I-SMALL: # %bb.0: 35; RV32I-SMALL-NEXT: lui a0, %hi(addr) 36; RV32I-SMALL-NEXT: li a1, 1 37; RV32I-SMALL-NEXT: sw a1, %lo(addr)(a0) 38; RV32I-SMALL-NEXT: ret 39; 40; RV32I-MEDIUM-LABEL: lower_blockaddress: 41; RV32I-MEDIUM: # %bb.0: 42; RV32I-MEDIUM-NEXT: .LBB1_1: # Label of block must be emitted 43; RV32I-MEDIUM-NEXT: auipc a0, %pcrel_hi(addr) 44; RV32I-MEDIUM-NEXT: addi a0, a0, %pcrel_lo(.LBB1_1) 45; RV32I-MEDIUM-NEXT: li a1, 1 46; RV32I-MEDIUM-NEXT: sw a1, 0(a0) 47; RV32I-MEDIUM-NEXT: ret 48 store volatile i8* blockaddress(@lower_blockaddress, %block), i8** @addr 49 ret void 50 51block: 52 unreachable 53} 54 55; Check lowering of blockaddress that forces a displacement to be added 56 57define signext i32 @lower_blockaddress_displ(i32 signext %w) nounwind { 58; RV32I-SMALL-LABEL: lower_blockaddress_displ: 59; RV32I-SMALL: # %bb.0: # %entry 60; RV32I-SMALL-NEXT: addi sp, sp, -16 61; RV32I-SMALL-NEXT: lui a1, %hi(.Ltmp0) 62; RV32I-SMALL-NEXT: addi a1, a1, %lo(.Ltmp0) 63; RV32I-SMALL-NEXT: li a2, 101 64; RV32I-SMALL-NEXT: sw a1, 8(sp) 65; RV32I-SMALL-NEXT: blt a0, a2, .LBB2_3 66; RV32I-SMALL-NEXT: # %bb.1: # %if.then 67; RV32I-SMALL-NEXT: lw a0, 8(sp) 68; RV32I-SMALL-NEXT: jr a0 69; RV32I-SMALL-NEXT: .Ltmp0: # Block address taken 70; RV32I-SMALL-NEXT: .LBB2_2: # %return 71; RV32I-SMALL-NEXT: li a0, 4 72; RV32I-SMALL-NEXT: addi sp, sp, 16 73; RV32I-SMALL-NEXT: ret 74; RV32I-SMALL-NEXT: .LBB2_3: # %return.clone 75; RV32I-SMALL-NEXT: li a0, 3 76; RV32I-SMALL-NEXT: addi sp, sp, 16 77; RV32I-SMALL-NEXT: ret 78; 79; RV32I-MEDIUM-LABEL: lower_blockaddress_displ: 80; RV32I-MEDIUM: # %bb.0: # %entry 81; RV32I-MEDIUM-NEXT: addi sp, sp, -16 82; RV32I-MEDIUM-NEXT: .LBB2_4: # %entry 83; RV32I-MEDIUM-NEXT: # Label of block must be emitted 84; RV32I-MEDIUM-NEXT: auipc a1, %pcrel_hi(.Ltmp0) 85; RV32I-MEDIUM-NEXT: addi a1, a1, %pcrel_lo(.LBB2_4) 86; RV32I-MEDIUM-NEXT: li a2, 101 87; RV32I-MEDIUM-NEXT: sw a1, 8(sp) 88; RV32I-MEDIUM-NEXT: blt a0, a2, .LBB2_3 89; RV32I-MEDIUM-NEXT: # %bb.1: # %if.then 90; RV32I-MEDIUM-NEXT: lw a0, 8(sp) 91; RV32I-MEDIUM-NEXT: jr a0 92; RV32I-MEDIUM-NEXT: .Ltmp0: # Block address taken 93; RV32I-MEDIUM-NEXT: .LBB2_2: # %return 94; RV32I-MEDIUM-NEXT: li a0, 4 95; RV32I-MEDIUM-NEXT: addi sp, sp, 16 96; RV32I-MEDIUM-NEXT: ret 97; RV32I-MEDIUM-NEXT: .LBB2_3: # %return.clone 98; RV32I-MEDIUM-NEXT: li a0, 3 99; RV32I-MEDIUM-NEXT: addi sp, sp, 16 100; RV32I-MEDIUM-NEXT: ret 101entry: 102 %x = alloca i8*, align 8 103 store i8* blockaddress(@lower_blockaddress_displ, %test_block), i8** %x, align 8 104 %cmp = icmp sgt i32 %w, 100 105 br i1 %cmp, label %if.then, label %if.end 106 107if.then: 108 %addr = load i8*, i8** %x, align 8 109 br label %indirectgoto 110 111if.end: 112 br label %return 113 114test_block: 115 br label %return 116 117return: 118 %retval = phi i32 [ 3, %if.end ], [ 4, %test_block ] 119 ret i32 %retval 120 121indirectgoto: 122 indirectbr i8* %addr, [ label %test_block ] 123} 124 125; Check lowering of constantpools 126 127define float @lower_constantpool(float %a) nounwind { 128; RV32I-SMALL-LABEL: lower_constantpool: 129; RV32I-SMALL: # %bb.0: 130; RV32I-SMALL-NEXT: lui a0, %hi(.LCPI3_0) 131; RV32I-SMALL-NEXT: flw ft0, %lo(.LCPI3_0)(a0) 132; RV32I-SMALL-NEXT: fadd.s fa0, fa0, ft0 133; RV32I-SMALL-NEXT: ret 134; 135; RV32I-MEDIUM-LABEL: lower_constantpool: 136; RV32I-MEDIUM: # %bb.0: 137; RV32I-MEDIUM-NEXT: .LBB3_1: # Label of block must be emitted 138; RV32I-MEDIUM-NEXT: auipc a0, %pcrel_hi(.LCPI3_0) 139; RV32I-MEDIUM-NEXT: addi a0, a0, %pcrel_lo(.LBB3_1) 140; RV32I-MEDIUM-NEXT: flw ft0, 0(a0) 141; RV32I-MEDIUM-NEXT: fadd.s fa0, fa0, ft0 142; RV32I-MEDIUM-NEXT: ret 143 %1 = fadd float %a, 1.0 144 ret float %1 145} 146