[InstCombine] Signed saturation patterns
[llvm-complete.git] / test / CodeGen / RISCV / codemodel-lowering.ll
blob6430a221e687271a32f62df15f32477275c5fabc
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=riscv32 -mattr=+f -code-model=small -verify-machineinstrs < %s \
3 ; RUN:   | FileCheck %s -check-prefix=RV32I-SMALL
4 ; RUN: llc -mtriple=riscv32 -mattr=+f -code-model=medium -verify-machineinstrs < %s \
5 ; RUN:   | FileCheck %s -check-prefix=RV32I-MEDIUM
7 ; Check lowering of globals
8 @G = global i32 0
10 define 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
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
28 ; Check lowering of blockaddresses
30 @addr = global i8* null
32 define 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:    addi a1, zero, 1
37 ; RV32I-SMALL-NEXT:    sw a1, %lo(addr)(a0)
38 ; RV32I-SMALL-NEXT:    ret
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:    addi a1, zero, 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
51 block:
52   unreachable
55 ; Check lowering of blockaddress that forces a displacement to be added
57 define 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:    sw ra, 12(sp)
62 ; RV32I-SMALL-NEXT:    lui a1, %hi(.Ltmp0)
63 ; RV32I-SMALL-NEXT:    addi a1, a1, %lo(.Ltmp0)
64 ; RV32I-SMALL-NEXT:    addi a2, zero, 101
65 ; RV32I-SMALL-NEXT:    sw a1, 8(sp)
66 ; RV32I-SMALL-NEXT:    blt a0, a2, .LBB2_3
67 ; RV32I-SMALL-NEXT:  # %bb.1: # %if.then
68 ; RV32I-SMALL-NEXT:    lw a0, 8(sp)
69 ; RV32I-SMALL-NEXT:    jr a0
70 ; RV32I-SMALL-NEXT:  .Ltmp0: # Block address taken
71 ; RV32I-SMALL-NEXT:  .LBB2_2: # %return
72 ; RV32I-SMALL-NEXT:    addi a0, zero, 4
73 ; RV32I-SMALL-NEXT:    j .LBB2_4
74 ; RV32I-SMALL-NEXT:  .LBB2_3: # %return.clone
75 ; RV32I-SMALL-NEXT:    addi a0, zero, 3
76 ; RV32I-SMALL-NEXT:  .LBB2_4: # %.split
77 ; RV32I-SMALL-NEXT:    lw ra, 12(sp)
78 ; RV32I-SMALL-NEXT:    addi sp, sp, 16
79 ; RV32I-SMALL-NEXT:    ret
81 ; RV32I-MEDIUM-LABEL: lower_blockaddress_displ:
82 ; RV32I-MEDIUM:       # %bb.0: # %entry
83 ; RV32I-MEDIUM-NEXT:    addi sp, sp, -16
84 ; RV32I-MEDIUM-NEXT:    sw ra, 12(sp)
85 ; RV32I-MEDIUM-NEXT:  .LBB2_5: # %entry
86 ; RV32I-MEDIUM-NEXT:    # Label of block must be emitted
87 ; RV32I-MEDIUM-NEXT:    auipc a1, %pcrel_hi(.Ltmp0)
88 ; RV32I-MEDIUM-NEXT:    addi a1, a1, %pcrel_lo(.LBB2_5)
89 ; RV32I-MEDIUM-NEXT:    addi a2, zero, 101
90 ; RV32I-MEDIUM-NEXT:    sw a1, 8(sp)
91 ; RV32I-MEDIUM-NEXT:    blt a0, a2, .LBB2_3
92 ; RV32I-MEDIUM-NEXT:  # %bb.1: # %if.then
93 ; RV32I-MEDIUM-NEXT:    lw a0, 8(sp)
94 ; RV32I-MEDIUM-NEXT:    jr a0
95 ; RV32I-MEDIUM-NEXT:  .Ltmp0: # Block address taken
96 ; RV32I-MEDIUM-NEXT:  .LBB2_2: # %return
97 ; RV32I-MEDIUM-NEXT:    addi a0, zero, 4
98 ; RV32I-MEDIUM-NEXT:    j .LBB2_4
99 ; RV32I-MEDIUM-NEXT:  .LBB2_3: # %return.clone
100 ; RV32I-MEDIUM-NEXT:    addi a0, zero, 3
101 ; RV32I-MEDIUM-NEXT:  .LBB2_4: # %.split
102 ; RV32I-MEDIUM-NEXT:    lw ra, 12(sp)
103 ; RV32I-MEDIUM-NEXT:    addi sp, sp, 16
104 ; RV32I-MEDIUM-NEXT:    ret
105 entry:
106   %x = alloca i8*, align 8
107   store i8* blockaddress(@lower_blockaddress_displ, %test_block), i8** %x, align 8
108   %cmp = icmp sgt i32 %w, 100
109   br i1 %cmp, label %if.then, label %if.end
111 if.then:
112   %addr = load i8*, i8** %x, align 8
113   br label %indirectgoto
115 if.end:
116   br label %return
118 test_block:
119   br label %return
121 return:
122   %retval = phi i32 [ 3, %if.end ], [ 4, %test_block ]
123   ret i32 %retval
125 indirectgoto:
126   indirectbr i8* %addr, [ label %test_block ]
129 ; Check lowering of constantpools
131 define float @lower_constantpool(float %a) nounwind {
132 ; RV32I-SMALL-LABEL: lower_constantpool:
133 ; RV32I-SMALL:       # %bb.0:
134 ; RV32I-SMALL-NEXT:    lui a1, %hi(.LCPI3_0)
135 ; RV32I-SMALL-NEXT:    addi a1, a1, %lo(.LCPI3_0)
136 ; RV32I-SMALL-NEXT:    flw ft0, 0(a1)
137 ; RV32I-SMALL-NEXT:    fmv.w.x ft1, a0
138 ; RV32I-SMALL-NEXT:    fadd.s ft0, ft1, ft0
139 ; RV32I-SMALL-NEXT:    fmv.x.w a0, ft0
140 ; RV32I-SMALL-NEXT:    ret
142 ; RV32I-MEDIUM-LABEL: lower_constantpool:
143 ; RV32I-MEDIUM:       # %bb.0:
144 ; RV32I-MEDIUM-NEXT:  .LBB3_1: # Label of block must be emitted
145 ; RV32I-MEDIUM-NEXT:    auipc a1, %pcrel_hi(.LCPI3_0)
146 ; RV32I-MEDIUM-NEXT:    addi a1, a1, %pcrel_lo(.LBB3_1)
147 ; RV32I-MEDIUM-NEXT:    flw ft0, 0(a1)
148 ; RV32I-MEDIUM-NEXT:    fmv.w.x ft1, a0
149 ; RV32I-MEDIUM-NEXT:    fadd.s ft0, ft1, ft0
150 ; RV32I-MEDIUM-NEXT:    fmv.x.w a0, ft0
151 ; RV32I-MEDIUM-NEXT:    ret
152   %1 = fadd float %a, 1.0
153   ret float %1