1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=aarch64 %s -o - | FileCheck %s --check-prefixes=CHECK,SDAG 3; RUN: llc -mtriple=aarch64 -global-isel -global-isel-abort=1 %s -o - | FileCheck %s --check-prefixes=CHECK,GISEL 4 5; These tests just check that the plumbing is in place for @llvm.bitreverse. 6 7declare <2 x i16> @llvm.bitreverse.v2i16(<2 x i16>) readnone 8 9define <2 x i16> @f(<2 x i16> %a) { 10; SDAG-LABEL: f: 11; SDAG: // %bb.0: 12; SDAG-NEXT: rev32 v0.8b, v0.8b 13; SDAG-NEXT: rbit v0.8b, v0.8b 14; SDAG-NEXT: ushr v0.2s, v0.2s, #16 15; SDAG-NEXT: ret 16; 17; GISEL-LABEL: f: 18; GISEL: // %bb.0: 19; GISEL-NEXT: uzp1 v0.4h, v0.4h, v0.4h 20; GISEL-NEXT: mov w8, #61680 // =0xf0f0 21; GISEL-NEXT: dup v1.2s, w8 22; GISEL-NEXT: mov w8, #4 // =0x4 23; GISEL-NEXT: fmov s3, w8 24; GISEL-NEXT: rev16 v0.8b, v0.8b 25; GISEL-NEXT: mov v3.h[1], w8 26; GISEL-NEXT: mov w8, #52428 // =0xcccc 27; GISEL-NEXT: ushll v2.4s, v0.4h, #0 28; GISEL-NEXT: neg v4.4h, v3.4h 29; GISEL-NEXT: and v2.8b, v2.8b, v1.8b 30; GISEL-NEXT: uzp1 v2.4h, v2.4h, v0.4h 31; GISEL-NEXT: ushl v0.4h, v0.4h, v3.4h 32; GISEL-NEXT: ushll v0.4s, v0.4h, #0 33; GISEL-NEXT: ushl v2.4h, v2.4h, v4.4h 34; GISEL-NEXT: and v0.8b, v0.8b, v1.8b 35; GISEL-NEXT: ushll v1.4s, v2.4h, #0 36; GISEL-NEXT: dup v2.2s, w8 37; GISEL-NEXT: mov w8, #2 // =0x2 38; GISEL-NEXT: orr v0.8b, v1.8b, v0.8b 39; GISEL-NEXT: fmov s1, w8 40; GISEL-NEXT: and v3.8b, v0.8b, v2.8b 41; GISEL-NEXT: uzp1 v0.4h, v0.4h, v0.4h 42; GISEL-NEXT: mov v1.h[1], w8 43; GISEL-NEXT: mov w8, #43690 // =0xaaaa 44; GISEL-NEXT: uzp1 v3.4h, v3.4h, v0.4h 45; GISEL-NEXT: neg v4.4h, v1.4h 46; GISEL-NEXT: ushl v0.4h, v0.4h, v1.4h 47; GISEL-NEXT: ushll v0.4s, v0.4h, #0 48; GISEL-NEXT: ushl v1.4h, v3.4h, v4.4h 49; GISEL-NEXT: and v0.8b, v0.8b, v2.8b 50; GISEL-NEXT: dup v2.2s, w8 51; GISEL-NEXT: mov w8, #1 // =0x1 52; GISEL-NEXT: ushll v1.4s, v1.4h, #0 53; GISEL-NEXT: orr v0.8b, v1.8b, v0.8b 54; GISEL-NEXT: fmov s1, w8 55; GISEL-NEXT: and v3.8b, v0.8b, v2.8b 56; GISEL-NEXT: uzp1 v0.4h, v0.4h, v0.4h 57; GISEL-NEXT: mov v1.h[1], w8 58; GISEL-NEXT: uzp1 v3.4h, v3.4h, v0.4h 59; GISEL-NEXT: neg v4.4h, v1.4h 60; GISEL-NEXT: ushl v0.4h, v0.4h, v1.4h 61; GISEL-NEXT: ushll v0.4s, v0.4h, #0 62; GISEL-NEXT: ushl v1.4h, v3.4h, v4.4h 63; GISEL-NEXT: and v0.8b, v0.8b, v2.8b 64; GISEL-NEXT: ushll v1.4s, v1.4h, #0 65; GISEL-NEXT: orr v0.8b, v1.8b, v0.8b 66; GISEL-NEXT: ret 67 %b = call <2 x i16> @llvm.bitreverse.v2i16(<2 x i16> %a) 68 ret <2 x i16> %b 69} 70 71declare i8 @llvm.bitreverse.i8(i8) readnone 72 73define i8 @g(i8 %a) { 74; CHECK-LABEL: g: 75; CHECK: // %bb.0: 76; CHECK-NEXT: rbit w8, w0 77; CHECK-NEXT: lsr w0, w8, #24 78; CHECK-NEXT: ret 79 %b = call i8 @llvm.bitreverse.i8(i8 %a) 80 ret i8 %b 81} 82 83declare i16 @llvm.bitreverse.i16(i16) readnone 84 85define i16 @g_16(i16 %a) { 86; CHECK-LABEL: g_16: 87; CHECK: // %bb.0: 88; CHECK-NEXT: rbit w8, w0 89; CHECK-NEXT: lsr w0, w8, #16 90; CHECK-NEXT: ret 91 %b = call i16 @llvm.bitreverse.i16(i16 %a) 92 ret i16 %b 93} 94 95declare i32 @llvm.bitreverse.i32(i32) readnone 96 97define i32 @g_32(i32 %a) { 98; CHECK-LABEL: g_32: 99; CHECK: // %bb.0: 100; CHECK-NEXT: rbit w0, w0 101; CHECK-NEXT: ret 102 %b = call i32 @llvm.bitreverse.i32(i32 %a) 103 ret i32 %b 104} 105 106declare i64 @llvm.bitreverse.i64(i64) readnone 107 108define i64 @g_64(i64 %a) { 109; CHECK-LABEL: g_64: 110; CHECK: // %bb.0: 111; CHECK-NEXT: rbit x0, x0 112; CHECK-NEXT: ret 113 %b = call i64 @llvm.bitreverse.i64(i64 %a) 114 ret i64 %b 115} 116 117declare <8 x i8> @llvm.bitreverse.v8i8(<8 x i8>) readnone 118 119define <8 x i8> @g_vec(<8 x i8> %a) { 120; CHECK-LABEL: g_vec: 121; CHECK: // %bb.0: 122; CHECK-NEXT: rbit v0.8b, v0.8b 123; CHECK-NEXT: ret 124 %b = call <8 x i8> @llvm.bitreverse.v8i8(<8 x i8> %a) 125 ret <8 x i8> %b 126} 127 128declare <16 x i8> @llvm.bitreverse.v16i8(<16 x i8>) readnone 129 130define <16 x i8> @g_vec_16x8(<16 x i8> %a) { 131; CHECK-LABEL: g_vec_16x8: 132; CHECK: // %bb.0: 133; CHECK-NEXT: rbit v0.16b, v0.16b 134; CHECK-NEXT: ret 135 %b = call <16 x i8> @llvm.bitreverse.v16i8(<16 x i8> %a) 136 ret <16 x i8> %b 137} 138 139declare <4 x i16> @llvm.bitreverse.v4i16(<4 x i16>) readnone 140 141define <4 x i16> @g_vec_4x16(<4 x i16> %a) { 142; SDAG-LABEL: g_vec_4x16: 143; SDAG: // %bb.0: 144; SDAG-NEXT: rev16 v0.8b, v0.8b 145; SDAG-NEXT: rbit v0.8b, v0.8b 146; SDAG-NEXT: ret 147; 148; GISEL-LABEL: g_vec_4x16: 149; GISEL: // %bb.0: 150; GISEL-NEXT: movi v1.8b, #240 151; GISEL-NEXT: rev16 v0.8b, v0.8b 152; GISEL-NEXT: and v2.8b, v0.8b, v1.8b 153; GISEL-NEXT: shl v0.4h, v0.4h, #4 154; GISEL-NEXT: ushr v2.4h, v2.4h, #4 155; GISEL-NEXT: and v0.8b, v0.8b, v1.8b 156; GISEL-NEXT: movi v1.8b, #204 157; GISEL-NEXT: orr v0.8b, v2.8b, v0.8b 158; GISEL-NEXT: and v2.8b, v0.8b, v1.8b 159; GISEL-NEXT: shl v0.4h, v0.4h, #2 160; GISEL-NEXT: ushr v2.4h, v2.4h, #2 161; GISEL-NEXT: and v0.8b, v0.8b, v1.8b 162; GISEL-NEXT: movi v1.8b, #170 163; GISEL-NEXT: orr v0.8b, v2.8b, v0.8b 164; GISEL-NEXT: and v2.8b, v0.8b, v1.8b 165; GISEL-NEXT: shl v0.4h, v0.4h, #1 166; GISEL-NEXT: ushr v2.4h, v2.4h, #1 167; GISEL-NEXT: and v0.8b, v0.8b, v1.8b 168; GISEL-NEXT: orr v0.8b, v2.8b, v0.8b 169; GISEL-NEXT: ret 170 %b = call <4 x i16> @llvm.bitreverse.v4i16(<4 x i16> %a) 171 ret <4 x i16> %b 172} 173 174declare <8 x i16> @llvm.bitreverse.v8i16(<8 x i16>) readnone 175 176define <8 x i16> @g_vec_8x16(<8 x i16> %a) { 177; SDAG-LABEL: g_vec_8x16: 178; SDAG: // %bb.0: 179; SDAG-NEXT: rev16 v0.16b, v0.16b 180; SDAG-NEXT: rbit v0.16b, v0.16b 181; SDAG-NEXT: ret 182; 183; GISEL-LABEL: g_vec_8x16: 184; GISEL: // %bb.0: 185; GISEL-NEXT: movi v1.16b, #240 186; GISEL-NEXT: rev16 v0.16b, v0.16b 187; GISEL-NEXT: and v2.16b, v0.16b, v1.16b 188; GISEL-NEXT: shl v0.8h, v0.8h, #4 189; GISEL-NEXT: ushr v2.8h, v2.8h, #4 190; GISEL-NEXT: and v0.16b, v0.16b, v1.16b 191; GISEL-NEXT: movi v1.16b, #204 192; GISEL-NEXT: orr v0.16b, v2.16b, v0.16b 193; GISEL-NEXT: and v2.16b, v0.16b, v1.16b 194; GISEL-NEXT: shl v0.8h, v0.8h, #2 195; GISEL-NEXT: ushr v2.8h, v2.8h, #2 196; GISEL-NEXT: and v0.16b, v0.16b, v1.16b 197; GISEL-NEXT: movi v1.16b, #170 198; GISEL-NEXT: orr v0.16b, v2.16b, v0.16b 199; GISEL-NEXT: and v2.16b, v0.16b, v1.16b 200; GISEL-NEXT: shl v0.8h, v0.8h, #1 201; GISEL-NEXT: ushr v2.8h, v2.8h, #1 202; GISEL-NEXT: and v0.16b, v0.16b, v1.16b 203; GISEL-NEXT: orr v0.16b, v2.16b, v0.16b 204; GISEL-NEXT: ret 205 %b = call <8 x i16> @llvm.bitreverse.v8i16(<8 x i16> %a) 206 ret <8 x i16> %b 207} 208 209declare <2 x i32> @llvm.bitreverse.v2i32(<2 x i32>) readnone 210 211define <2 x i32> @g_vec_2x32(<2 x i32> %a) { 212; SDAG-LABEL: g_vec_2x32: 213; SDAG: // %bb.0: 214; SDAG-NEXT: rev32 v0.8b, v0.8b 215; SDAG-NEXT: rbit v0.8b, v0.8b 216; SDAG-NEXT: ret 217; 218; GISEL-LABEL: g_vec_2x32: 219; GISEL: // %bb.0: 220; GISEL-NEXT: movi v1.8b, #240 221; GISEL-NEXT: rev32 v0.8b, v0.8b 222; GISEL-NEXT: and v2.8b, v0.8b, v1.8b 223; GISEL-NEXT: shl v0.2s, v0.2s, #4 224; GISEL-NEXT: ushr v2.2s, v2.2s, #4 225; GISEL-NEXT: and v0.8b, v0.8b, v1.8b 226; GISEL-NEXT: movi v1.8b, #204 227; GISEL-NEXT: orr v0.8b, v2.8b, v0.8b 228; GISEL-NEXT: and v2.8b, v0.8b, v1.8b 229; GISEL-NEXT: shl v0.2s, v0.2s, #2 230; GISEL-NEXT: ushr v2.2s, v2.2s, #2 231; GISEL-NEXT: and v0.8b, v0.8b, v1.8b 232; GISEL-NEXT: movi v1.8b, #170 233; GISEL-NEXT: orr v0.8b, v2.8b, v0.8b 234; GISEL-NEXT: and v2.8b, v0.8b, v1.8b 235; GISEL-NEXT: shl v0.2s, v0.2s, #1 236; GISEL-NEXT: ushr v2.2s, v2.2s, #1 237; GISEL-NEXT: and v0.8b, v0.8b, v1.8b 238; GISEL-NEXT: orr v0.8b, v2.8b, v0.8b 239; GISEL-NEXT: ret 240 %b = call <2 x i32> @llvm.bitreverse.v2i32(<2 x i32> %a) 241 ret <2 x i32> %b 242} 243 244declare <4 x i32> @llvm.bitreverse.v4i32(<4 x i32>) readnone 245 246define <4 x i32> @g_vec_4x32(<4 x i32> %a) { 247; SDAG-LABEL: g_vec_4x32: 248; SDAG: // %bb.0: 249; SDAG-NEXT: rev32 v0.16b, v0.16b 250; SDAG-NEXT: rbit v0.16b, v0.16b 251; SDAG-NEXT: ret 252; 253; GISEL-LABEL: g_vec_4x32: 254; GISEL: // %bb.0: 255; GISEL-NEXT: movi v1.16b, #240 256; GISEL-NEXT: rev32 v0.16b, v0.16b 257; GISEL-NEXT: and v2.16b, v0.16b, v1.16b 258; GISEL-NEXT: shl v0.4s, v0.4s, #4 259; GISEL-NEXT: ushr v2.4s, v2.4s, #4 260; GISEL-NEXT: and v0.16b, v0.16b, v1.16b 261; GISEL-NEXT: movi v1.16b, #204 262; GISEL-NEXT: orr v0.16b, v2.16b, v0.16b 263; GISEL-NEXT: and v2.16b, v0.16b, v1.16b 264; GISEL-NEXT: shl v0.4s, v0.4s, #2 265; GISEL-NEXT: ushr v2.4s, v2.4s, #2 266; GISEL-NEXT: and v0.16b, v0.16b, v1.16b 267; GISEL-NEXT: movi v1.16b, #170 268; GISEL-NEXT: orr v0.16b, v2.16b, v0.16b 269; GISEL-NEXT: and v2.16b, v0.16b, v1.16b 270; GISEL-NEXT: shl v0.4s, v0.4s, #1 271; GISEL-NEXT: ushr v2.4s, v2.4s, #1 272; GISEL-NEXT: and v0.16b, v0.16b, v1.16b 273; GISEL-NEXT: orr v0.16b, v2.16b, v0.16b 274; GISEL-NEXT: ret 275 %b = call <4 x i32> @llvm.bitreverse.v4i32(<4 x i32> %a) 276 ret <4 x i32> %b 277} 278 279declare <1 x i64> @llvm.bitreverse.v1i64(<1 x i64>) readnone 280 281define <1 x i64> @g_vec_1x64(<1 x i64> %a) { 282; SDAG-LABEL: g_vec_1x64: 283; SDAG: // %bb.0: 284; SDAG-NEXT: rev64 v0.8b, v0.8b 285; SDAG-NEXT: rbit v0.8b, v0.8b 286; SDAG-NEXT: ret 287; 288; GISEL-LABEL: g_vec_1x64: 289; GISEL: // %bb.0: 290; GISEL-NEXT: fmov x8, d0 291; GISEL-NEXT: rbit x8, x8 292; GISEL-NEXT: fmov d0, x8 293; GISEL-NEXT: ret 294 %b = call <1 x i64> @llvm.bitreverse.v1i64(<1 x i64> %a) 295 ret <1 x i64> %b 296} 297 298declare <2 x i64> @llvm.bitreverse.v2i64(<2 x i64>) readnone 299 300define <2 x i64> @g_vec_2x64(<2 x i64> %a) { 301; SDAG-LABEL: g_vec_2x64: 302; SDAG: // %bb.0: 303; SDAG-NEXT: rev64 v0.16b, v0.16b 304; SDAG-NEXT: rbit v0.16b, v0.16b 305; SDAG-NEXT: ret 306; 307; GISEL-LABEL: g_vec_2x64: 308; GISEL: // %bb.0: 309; GISEL-NEXT: movi v1.16b, #240 310; GISEL-NEXT: rev64 v0.16b, v0.16b 311; GISEL-NEXT: and v2.16b, v0.16b, v1.16b 312; GISEL-NEXT: shl v0.2d, v0.2d, #4 313; GISEL-NEXT: ushr v2.2d, v2.2d, #4 314; GISEL-NEXT: and v0.16b, v0.16b, v1.16b 315; GISEL-NEXT: movi v1.16b, #204 316; GISEL-NEXT: orr v0.16b, v2.16b, v0.16b 317; GISEL-NEXT: and v2.16b, v0.16b, v1.16b 318; GISEL-NEXT: shl v0.2d, v0.2d, #2 319; GISEL-NEXT: ushr v2.2d, v2.2d, #2 320; GISEL-NEXT: and v0.16b, v0.16b, v1.16b 321; GISEL-NEXT: movi v1.16b, #170 322; GISEL-NEXT: orr v0.16b, v2.16b, v0.16b 323; GISEL-NEXT: and v2.16b, v0.16b, v1.16b 324; GISEL-NEXT: shl v0.2d, v0.2d, #1 325; GISEL-NEXT: ushr v2.2d, v2.2d, #1 326; GISEL-NEXT: and v0.16b, v0.16b, v1.16b 327; GISEL-NEXT: orr v0.16b, v2.16b, v0.16b 328; GISEL-NEXT: ret 329 %b = call <2 x i64> @llvm.bitreverse.v2i64(<2 x i64> %a) 330 ret <2 x i64> %b 331} 332