xref: /llvm-project/llvm/test/CodeGen/PowerPC/p10-bswap.ll (revision ee559b21b961c2889837c349b73e08a7b5dafa55)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \
3; RUN:     -mcpu=pwr10 -ppc-asm-full-reg-names < %s | FileCheck %s
4
5; Check that the brh/brw/brd instructions are generated for the bswap
6; intrinsic for register operand on P10 and that the lhbrx/lwbrx/ldbrw
7; instructions are generated for memory operand.
8
9declare i16 @llvm.bswap.i16(i16)
10
11define zeroext i16 @test_nomem16(i16 zeroext %a) {
12; CHECK-LABEL: test_nomem16:
13; CHECK:       # %bb.0: # %entry
14; CHECK-NEXT:    brh r3, r3
15; CHECK-NEXT:    clrldi r3, r3, 48
16; CHECK-NEXT:    blr
17entry:
18  %0 = tail call i16 @llvm.bswap.i16(i16 %a)
19  ret i16 %0
20}
21
22declare i32 @llvm.bswap.i32(i32)
23
24define zeroext i32 @test_nomem32(i32 zeroext %a) {
25; CHECK-LABEL: test_nomem32:
26; CHECK:       # %bb.0: # %entry
27; CHECK-NEXT:    brw r3, r3
28; CHECK-NEXT:    clrldi r3, r3, 32
29; CHECK-NEXT:    blr
30entry:
31  %0 = tail call i32 @llvm.bswap.i32(i32 %a)
32  ret i32 %0
33}
34
35; Check that brh and clrldi are produced from a call to @llvm.bswap.i32
36; followed by a right shift of 16 (and a zero-extend at the end of the DAG).
37define zeroext i32 @test_bswap_shift16(i32 zeroext %a) {
38; CHECK-LABEL: test_bswap_shift16:
39; CHECK:       # %bb.0: # %entry
40; CHECK-NEXT:    brh r3, r3
41; CHECK-NEXT:    clrldi r3, r3, 48
42; CHECK-NEXT:    blr
43entry:
44  %0 = tail call i32 @llvm.bswap.i32(i32 %a)
45  %shr = lshr i32 %0, 16
46  ret i32 %shr
47}
48
49; Check that brh are produced from a call to @llvm.bswap.i32
50; followed by a right shift of 16.
51declare i64 @call_1()
52define void @test_bswap_shift16_2() {
53; CHECK-LABEL: test_bswap_shift16_2:
54; CHECK:       # %bb.0: # %bb
55; CHECK-NEXT:    mflr r0
56; CHECK-NEXT:    std r0, 16(r1)
57; CHECK-NEXT:    stdu r1, -32(r1)
58; CHECK-NEXT:    .cfi_def_cfa_offset 32
59; CHECK-NEXT:    .cfi_offset lr, 16
60; CHECK-NEXT:    bl call_1@notoc
61; CHECK-NEXT:    brh r3, r3
62; CHECK-NEXT:    rldicl r3, r3, 0, 48
63; CHECK-NEXT:    sth r3, 0(r3)
64bb:
65  switch i32 undef, label %bb1 [
66    i32 78, label %bb2
67  ]
68
69bb1:
70  unreachable
71
72bb2:
73  %i = call i64 @call_1()
74  %i3 = trunc i64 %i to i32
75  %i4 = call i32 @llvm.bswap.i32(i32 %i3)
76  %i5 = lshr i32 %i4, 16
77  %i6 = trunc i32 %i5 to i16
78  store i16 %i6, ptr undef, align 2
79  unreachable
80}
81
82define zeroext i32 @test_bswap_shift18(i32 zeroext %a) {
83; CHECK-LABEL: test_bswap_shift18:
84; CHECK:       # %bb.0: # %entry
85; CHECK-NEXT:    brw r3, r3
86; CHECK-NEXT:    rlwinm r3, r3, 14, 18, 31
87; CHECK-NEXT:    blr
88entry:
89  %0 = tail call i32 @llvm.bswap.i32(i32 %a)
90  %shr = lshr i32 %0, 18
91  ret i32 %shr
92}
93
94declare i64 @llvm.bswap.i64(i64)
95
96define i64 @test_nomem64(i64 %a) {
97; CHECK-LABEL: test_nomem64:
98; CHECK:       # %bb.0: # %entry
99; CHECK-NEXT:    brd r3, r3
100; CHECK-NEXT:    blr
101entry:
102  %0 = tail call i64 @llvm.bswap.i64(i64 %a)
103  ret i64 %0
104}
105
106define i16 @test_mem16(ptr %a) {
107; CHECK-LABEL: test_mem16:
108; CHECK:       # %bb.0: # %entry
109; CHECK-NEXT:    lhbrx r3, 0, r3
110; CHECK-NEXT:    blr
111entry:
112  %0 = load i16, ptr %a, align 2
113  %1 = tail call i16 @llvm.bswap.i16(i16 %0)
114  ret i16 %1
115}
116
117define i32 @test_mem32(ptr %a) {
118; CHECK-LABEL: test_mem32:
119; CHECK:       # %bb.0: # %entry
120; CHECK-NEXT:    lwbrx r3, 0, r3
121; CHECK-NEXT:    blr
122entry:
123  %0 = load i32, ptr %a, align 4
124  %1 = tail call i32 @llvm.bswap.i32(i32 %0)
125  ret i32 %1
126}
127
128define i64 @test_mem64(ptr %a) {
129; CHECK-LABEL: test_mem64:
130; CHECK:       # %bb.0: # %entry
131; CHECK-NEXT:    ldbrx r3, 0, r3
132; CHECK-NEXT:    blr
133entry:
134  %0 = load i64, ptr %a, align 8
135  %1 = tail call i64 @llvm.bswap.i64(i64 %0)
136  ret i64 %1
137}
138
139