File: rv64i-shift-sext.ll

package info (click to toggle)
llvm-toolchain-15 1%3A15.0.6-4
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 1,554,644 kB
  • sloc: cpp: 5,922,452; ansic: 1,012,136; asm: 674,362; python: 191,568; objc: 73,855; f90: 42,327; lisp: 31,913; pascal: 11,973; javascript: 10,144; sh: 9,421; perl: 7,447; ml: 5,527; awk: 3,523; makefile: 2,520; xml: 885; cs: 573; fortran: 567
file content (172 lines) | stat: -rw-r--r-- 4,580 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
; RUN:   | FileCheck %s -check-prefix=RV64I

; Test that we turn (sra (shl X, 32), 32-C) into (slli (sext.w X), C)

define i64 @test1(i64 %a) nounwind {
; RV64I-LABEL: test1:
; RV64I:       # %bb.0:
; RV64I-NEXT:    sext.w a0, a0
; RV64I-NEXT:    slli a0, a0, 2
; RV64I-NEXT:    ret
  %1 = shl i64 %a, 32
  %2 = ashr i64 %1, 30
  ret i64 %2
}

define i64 @test2(i32 signext %a) nounwind {
; RV64I-LABEL: test2:
; RV64I:       # %bb.0:
; RV64I-NEXT:    slli a0, a0, 3
; RV64I-NEXT:    ret
  %1 = zext i32 %a to i64
  %2 = shl i64 %1, 32
  %3 = ashr i64 %2, 29
  ret i64 %3
}

define i64 @test3(i32* %a) nounwind {
; RV64I-LABEL: test3:
; RV64I:       # %bb.0:
; RV64I-NEXT:    lw a0, 0(a0)
; RV64I-NEXT:    slli a0, a0, 4
; RV64I-NEXT:    ret
  %1 = load i32, i32* %a
  %2 = zext i32 %1 to i64
  %3 = shl i64 %2, 32
  %4 = ashr i64 %3, 28
  ret i64 %4
}

define i64 @test4(i32 signext %a, i32 signext %b) nounwind {
; RV64I-LABEL: test4:
; RV64I:       # %bb.0:
; RV64I-NEXT:    addw a0, a0, a1
; RV64I-NEXT:    slli a0, a0, 30
; RV64I-NEXT:    ret
  %1 = add i32 %a, %b
  %2 = zext i32 %1 to i64
  %3 = shl i64 %2, 32
  %4 = ashr i64 %3, 2
  ret i64 %4
}

define i64 @test5(i32 signext %a, i32 signext %b) nounwind {
; RV64I-LABEL: test5:
; RV64I:       # %bb.0:
; RV64I-NEXT:    xor a0, a0, a1
; RV64I-NEXT:    slli a0, a0, 31
; RV64I-NEXT:    ret
  %1 = xor i32 %a, %b
  %2 = zext i32 %1 to i64
  %3 = shl i64 %2, 32
  %4 = ashr i64 %3, 1
  ret i64 %4
}

define i64 @test6(i32 signext %a, i32 signext %b) nounwind {
; RV64I-LABEL: test6:
; RV64I:       # %bb.0:
; RV64I-NEXT:    sllw a0, a0, a1
; RV64I-NEXT:    slli a0, a0, 16
; RV64I-NEXT:    ret
  %1 = shl i32 %a, %b
  %2 = zext i32 %1 to i64
  %3 = shl i64 %2, 32
  %4 = ashr i64 %3, 16
  ret i64 %4
}

; The ashr+add+shl is canonical IR from InstCombine for
; (sext (add (trunc X to i32), 1) to i32).
; That can be implemented as addiw make sure we recover it.
define i64 @test7(i32* %0, i64 %1) {
; RV64I-LABEL: test7:
; RV64I:       # %bb.0:
; RV64I-NEXT:    addiw a0, a1, 1
; RV64I-NEXT:    ret
  %3 = shl i64 %1, 32
  %4 = add i64 %3, 4294967296
  %5 = ashr exact i64 %4, 32
  ret i64 %5
}

; The ashr+add+shl is canonical IR from InstCombine for
; (sext (sub 1, (trunc X to i32)) to i32).
; That can be implemented as (li 1)+subw make sure we recover it.
define i64 @test8(i32* %0, i64 %1) {
; RV64I-LABEL: test8:
; RV64I:       # %bb.0:
; RV64I-NEXT:    li a0, 1
; RV64I-NEXT:    subw a0, a0, a1
; RV64I-NEXT:    ret
  %3 = mul i64 %1, -4294967296
  %4 = add i64 %3, 4294967296
  %5 = ashr exact i64 %4, 32
  ret i64 %5
}

; The gep is here to introduce a shl by 2 after the ashr that will get folded
; and make this harder to recover.
define signext i32 @test9(i32* %0, i64 %1) {
; RV64I-LABEL: test9:
; RV64I:       # %bb.0:
; RV64I-NEXT:    lui a2, 1
; RV64I-NEXT:    addiw a2, a2, 1
; RV64I-NEXT:    addw a1, a1, a2
; RV64I-NEXT:    slli a1, a1, 2
; RV64I-NEXT:    add a0, a0, a1
; RV64I-NEXT:    lw a0, 0(a0)
; RV64I-NEXT:    ret
  %3 = shl i64 %1, 32
  %4 = add i64 %3, 17596481011712 ; 4097 << 32
  %5 = ashr exact i64 %4, 32
  %6 = getelementptr inbounds i32, i32* %0, i64 %5
  %7 = load i32, i32* %6, align 4
  ret i32 %7
}

; The gep is here to introduce a shl by 2 after the ashr that will get folded
; and make this harder to recover.
define signext i32 @test10(i32* %0, i64 %1) {
; RV64I-LABEL: test10:
; RV64I:       # %bb.0:
; RV64I-NEXT:    lui a2, 30141
; RV64I-NEXT:    addiw a2, a2, -747
; RV64I-NEXT:    subw a1, a2, a1
; RV64I-NEXT:    slli a1, a1, 2
; RV64I-NEXT:    add a0, a0, a1
; RV64I-NEXT:    lw a0, 0(a0)
; RV64I-NEXT:    ret
  %3 = mul i64 %1, -4294967296
  %4 = add i64 %3, 530242871224172544 ; 123456789 << 32
  %5 = ashr exact i64 %4, 32
  %6 = getelementptr inbounds i32, i32* %0, i64 %5
  %7 = load i32, i32* %6, align 4
  ret i32 %7
}

define i64 @test11(i32* %0, i64 %1) {
; RV64I-LABEL: test11:
; RV64I:       # %bb.0:
; RV64I-NEXT:    lui a0, 524288
; RV64I-NEXT:    subw a0, a0, a1
; RV64I-NEXT:    ret
  %3 = mul i64 %1, -4294967296
  %4 = add i64 %3, 9223372036854775808 ;0x8000'0000'0000'0000
  %5 = ashr exact i64 %4, 32
  ret i64 %5
}

; Make sure we use slli+srai to enable the possibility of compressed
define i32 @test12(i32 signext %0) {
; RV64I-LABEL: test12:
; RV64I:       # %bb.0:
; RV64I-NEXT:    slli a0, a0, 49
; RV64I-NEXT:    srai a0, a0, 47
; RV64I-NEXT:    ret
  %2 = shl i32 %0, 17
  %3 = ashr i32 %2, 15
  ret i32 %3
}