brintos

brintos / llvm-project-archived public Read only

0
0
Text · 12.6 KiB · 191155a Raw
436 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=arm-eabi -mattr=+v6t2 | FileCheck %s --check-prefixes=CHECK,SCALAR3; RUN: llc < %s -mtriple=arm-eabi -mattr=+v6t2 -mattr=+neon | FileCheck %s --check-prefixes=CHECK,NEON4 5declare i8 @llvm.fshl.i8(i8, i8, i8)6declare i16 @llvm.fshl.i16(i16, i16, i16)7declare i32 @llvm.fshl.i32(i32, i32, i32)8declare i64 @llvm.fshl.i64(i64, i64, i64)9declare <4 x i32> @llvm.fshl.v4i32(<4 x i32>, <4 x i32>, <4 x i32>)10 11declare i8 @llvm.fshr.i8(i8, i8, i8)12declare i16 @llvm.fshr.i16(i16, i16, i16)13declare i32 @llvm.fshr.i32(i32, i32, i32)14declare i64 @llvm.fshr.i64(i64, i64, i64)15declare <4 x i32> @llvm.fshr.v4i32(<4 x i32>, <4 x i32>, <4 x i32>)16 17; General case - all operands can be variables.18 19define i16 @fshl_i16(i16 %x, i16 %y, i16 %z) {20; CHECK-LABEL: fshl_i16:21; CHECK:       @ %bb.0:22; CHECK-NEXT:    pkhbt r0, r1, r0, lsl #1623; CHECK-NEXT:    and r1, r2, #1524; CHECK-NEXT:    lsl r0, r0, r125; CHECK-NEXT:    lsr r0, r0, #1626; CHECK-NEXT:    bx lr27  %f = call i16 @llvm.fshl.i16(i16 %x, i16 %y, i16 %z)28  ret i16 %f29}30 31define i32 @fshl_i32(i32 %x, i32 %y, i32 %z) {32; CHECK-LABEL: fshl_i32:33; CHECK:       @ %bb.0:34; CHECK-NEXT:    mov r3, #3135; CHECK-NEXT:    lsr r1, r1, #136; CHECK-NEXT:    bic r3, r3, r237; CHECK-NEXT:    and r2, r2, #3138; CHECK-NEXT:    lsl r0, r0, r239; CHECK-NEXT:    orr r0, r0, r1, lsr r340; CHECK-NEXT:    bx lr41  %f = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 %z)42  ret i32 %f43}44 45; Verify that weird types are minimally supported.46declare i37 @llvm.fshl.i37(i37, i37, i37)47define i37 @fshl_i37(i37 %x, i37 %y, i37 %z) {48; SCALAR-LABEL: fshl_i37:49; SCALAR:       @ %bb.0:50; SCALAR-NEXT:    .save {r4, r5, r6, r7, r8, lr}51; SCALAR-NEXT:    push {r4, r5, r6, r7, r8, lr}52; SCALAR-NEXT:    mov r8, r053; SCALAR-NEXT:    ldr r0, [sp, #28]54; SCALAR-NEXT:    mov r4, r155; SCALAR-NEXT:    mov r5, r356; SCALAR-NEXT:    and r1, r0, #3157; SCALAR-NEXT:    ldr r0, [sp, #24]58; SCALAR-NEXT:    mov r6, r259; SCALAR-NEXT:    mov r2, #3760; SCALAR-NEXT:    mov r3, #061; SCALAR-NEXT:    bl __aeabi_uldivmod62; SCALAR-NEXT:    lsl r0, r5, #2763; SCALAR-NEXT:    tst r2, #3264; SCALAR-NEXT:    orr r0, r0, r6, lsr #565; SCALAR-NEXT:    mov r1, r866; SCALAR-NEXT:    and r3, r2, #3167; SCALAR-NEXT:    mov r7, #3168; SCALAR-NEXT:    movne r1, r069; SCALAR-NEXT:    lslne r0, r6, #2770; SCALAR-NEXT:    bic r2, r7, r271; SCALAR-NEXT:    lsl r5, r1, r372; SCALAR-NEXT:    lsr r0, r0, #173; SCALAR-NEXT:    movne r4, r874; SCALAR-NEXT:    lsr r1, r1, #175; SCALAR-NEXT:    lsl r3, r4, r376; SCALAR-NEXT:    orr r0, r5, r0, lsr r277; SCALAR-NEXT:    orr r1, r3, r1, lsr r278; SCALAR-NEXT:    pop {r4, r5, r6, r7, r8, pc}79;80; NEON-LABEL: fshl_i37:81; NEON:       @ %bb.0:82; NEON-NEXT:    .save {r4, r5, r6, r7, r8, lr}83; NEON-NEXT:    push {r4, r5, r6, r7, r8, lr}84; NEON-NEXT:    mov r4, r185; NEON-NEXT:    ldr r1, [sp, #28]86; NEON-NEXT:    mov r8, r087; NEON-NEXT:    ldr r0, [sp, #24]88; NEON-NEXT:    and r1, r1, #3189; NEON-NEXT:    mov r5, r390; NEON-NEXT:    mov r6, r291; NEON-NEXT:    mov r2, #3792; NEON-NEXT:    mov r3, #093; NEON-NEXT:    bl __aeabi_uldivmod94; NEON-NEXT:    lsl r0, r5, #2795; NEON-NEXT:    tst r2, #3296; NEON-NEXT:    orr r0, r0, r6, lsr #597; NEON-NEXT:    mov r1, r898; NEON-NEXT:    and r3, r2, #3199; NEON-NEXT:    mov r7, #31100; NEON-NEXT:    movne r1, r0101; NEON-NEXT:    lslne r0, r6, #27102; NEON-NEXT:    bic r2, r7, r2103; NEON-NEXT:    lsl r5, r1, r3104; NEON-NEXT:    lsr r0, r0, #1105; NEON-NEXT:    movne r4, r8106; NEON-NEXT:    lsr r1, r1, #1107; NEON-NEXT:    lsl r3, r4, r3108; NEON-NEXT:    orr r0, r5, r0, lsr r2109; NEON-NEXT:    orr r1, r3, r1, lsr r2110; NEON-NEXT:    pop {r4, r5, r6, r7, r8, pc}111  %f = call i37 @llvm.fshl.i37(i37 %x, i37 %y, i37 %z)112  ret i37 %f113}114 115; extract(concat(0b1110000, 0b1111111) << 2) = 0b1000011116 117declare i7 @llvm.fshl.i7(i7, i7, i7)118define i7 @fshl_i7_const_fold() {119; CHECK-LABEL: fshl_i7_const_fold:120; CHECK:       @ %bb.0:121; CHECK-NEXT:    mov r0, #67122; CHECK-NEXT:    bx lr123  %f = call i7 @llvm.fshl.i7(i7 112, i7 127, i7 2)124  ret i7 %f125}126 127define i8 @fshl_i8_const_fold_overshift_1() {128; CHECK-LABEL: fshl_i8_const_fold_overshift_1:129; CHECK:       @ %bb.0:130; CHECK-NEXT:    mov r0, #128131; CHECK-NEXT:    bx lr132  %f = call i8 @llvm.fshl.i8(i8 255, i8 0, i8 15)133  ret i8 %f134}135 136define i8 @fshl_i8_const_fold_overshift_2() {137; CHECK-LABEL: fshl_i8_const_fold_overshift_2:138; CHECK:       @ %bb.0:139; CHECK-NEXT:    mov r0, #120140; CHECK-NEXT:    bx lr141  %f = call i8 @llvm.fshl.i8(i8 15, i8 15, i8 11)142  ret i8 %f143}144 145define i8 @fshl_i8_const_fold_overshift_3() {146; CHECK-LABEL: fshl_i8_const_fold_overshift_3:147; CHECK:       @ %bb.0:148; CHECK-NEXT:    mov r0, #0149; CHECK-NEXT:    bx lr150  %f = call i8 @llvm.fshl.i8(i8 0, i8 225, i8 8)151  ret i8 %f152}153 154; With constant shift amount, this is 'extr'.155 156define i32 @fshl_i32_const_shift(i32 %x, i32 %y) {157; CHECK-LABEL: fshl_i32_const_shift:158; CHECK:       @ %bb.0:159; CHECK-NEXT:    lsl r0, r0, #9160; CHECK-NEXT:    orr r0, r0, r1, lsr #23161; CHECK-NEXT:    bx lr162  %f = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 9)163  ret i32 %f164}165 166; Check modulo math on shift amount.167 168define i32 @fshl_i32_const_overshift(i32 %x, i32 %y) {169; CHECK-LABEL: fshl_i32_const_overshift:170; CHECK:       @ %bb.0:171; CHECK-NEXT:    lsl r0, r0, #9172; CHECK-NEXT:    orr r0, r0, r1, lsr #23173; CHECK-NEXT:    bx lr174  %f = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 41)175  ret i32 %f176}177 178; 64-bit should also work.179 180define i64 @fshl_i64_const_overshift(i64 %x, i64 %y) {181; CHECK-LABEL: fshl_i64_const_overshift:182; CHECK:       @ %bb.0:183; CHECK-NEXT:    lsl r1, r3, #9184; CHECK-NEXT:    orr r2, r1, r2, lsr #23185; CHECK-NEXT:    lsl r0, r0, #9186; CHECK-NEXT:    orr r1, r0, r3, lsr #23187; CHECK-NEXT:    mov r0, r2188; CHECK-NEXT:    bx lr189  %f = call i64 @llvm.fshl.i64(i64 %x, i64 %y, i64 105)190  ret i64 %f191}192 193; This should work without any node-specific logic.194 195define i8 @fshl_i8_const_fold() {196; CHECK-LABEL: fshl_i8_const_fold:197; CHECK:       @ %bb.0:198; CHECK-NEXT:    mov r0, #128199; CHECK-NEXT:    bx lr200  %f = call i8 @llvm.fshl.i8(i8 255, i8 0, i8 7)201  ret i8 %f202}203 204; Repeat everything for funnel shift right.205 206; General case - all operands can be variables.207 208define i16 @fshr_i16(i16 %x, i16 %y, i16 %z) {209; CHECK-LABEL: fshr_i16:210; CHECK:       @ %bb.0:211; CHECK-NEXT:    pkhbt r0, r1, r0, lsl #16212; CHECK-NEXT:    and r1, r2, #15213; CHECK-NEXT:    lsr r0, r0, r1214; CHECK-NEXT:    bx lr215  %f = call i16 @llvm.fshr.i16(i16 %x, i16 %y, i16 %z)216  ret i16 %f217}218 219define i32 @fshr_i32(i32 %x, i32 %y, i32 %z) {220; CHECK-LABEL: fshr_i32:221; CHECK:       @ %bb.0:222; CHECK-NEXT:    mov r3, #31223; CHECK-NEXT:    lsl r0, r0, #1224; CHECK-NEXT:    bic r3, r3, r2225; CHECK-NEXT:    and r2, r2, #31226; CHECK-NEXT:    lsl r0, r0, r3227; CHECK-NEXT:    orr r0, r0, r1, lsr r2228; CHECK-NEXT:    bx lr229  %f = call i32 @llvm.fshr.i32(i32 %x, i32 %y, i32 %z)230  ret i32 %f231}232 233; Verify that weird types are minimally supported.234declare i37 @llvm.fshr.i37(i37, i37, i37)235define i37 @fshr_i37(i37 %x, i37 %y, i37 %z) {236; SCALAR-LABEL: fshr_i37:237; SCALAR:       @ %bb.0:238; SCALAR-NEXT:    .save {r4, r5, r6, r7, r11, lr}239; SCALAR-NEXT:    push {r4, r5, r6, r7, r11, lr}240; SCALAR-NEXT:    mov r5, r0241; SCALAR-NEXT:    ldr r0, [sp, #28]242; SCALAR-NEXT:    mov r4, r1243; SCALAR-NEXT:    mov r6, r3244; SCALAR-NEXT:    and r1, r0, #31245; SCALAR-NEXT:    ldr r0, [sp, #24]246; SCALAR-NEXT:    mov r7, r2247; SCALAR-NEXT:    mov r2, #37248; SCALAR-NEXT:    mov r3, #0249; SCALAR-NEXT:    bl __aeabi_uldivmod250; SCALAR-NEXT:    add r0, r2, #27251; SCALAR-NEXT:    lsl r2, r6, #27252; SCALAR-NEXT:    orr r2, r2, r7, lsr #5253; SCALAR-NEXT:    mov r1, #31254; SCALAR-NEXT:    tst r0, #32255; SCALAR-NEXT:    mov r3, r5256; SCALAR-NEXT:    moveq r3, r2257; SCALAR-NEXT:    lsleq r2, r7, #27258; SCALAR-NEXT:    bic r1, r1, r0259; SCALAR-NEXT:    and r7, r0, #31260; SCALAR-NEXT:    lsl r6, r3, #1261; SCALAR-NEXT:    moveq r4, r5262; SCALAR-NEXT:    lsl r6, r6, r1263; SCALAR-NEXT:    orr r0, r6, r2, lsr r7264; SCALAR-NEXT:    lsl r2, r4, #1265; SCALAR-NEXT:    lsl r1, r2, r1266; SCALAR-NEXT:    orr r1, r1, r3, lsr r7267; SCALAR-NEXT:    pop {r4, r5, r6, r7, r11, pc}268;269; NEON-LABEL: fshr_i37:270; NEON:       @ %bb.0:271; NEON-NEXT:    .save {r4, r5, r6, r7, r11, lr}272; NEON-NEXT:    push {r4, r5, r6, r7, r11, lr}273; NEON-NEXT:    mov r4, r1274; NEON-NEXT:    ldr r1, [sp, #28]275; NEON-NEXT:    mov r5, r0276; NEON-NEXT:    ldr r0, [sp, #24]277; NEON-NEXT:    and r1, r1, #31278; NEON-NEXT:    mov r6, r3279; NEON-NEXT:    mov r7, r2280; NEON-NEXT:    mov r2, #37281; NEON-NEXT:    mov r3, #0282; NEON-NEXT:    bl __aeabi_uldivmod283; NEON-NEXT:    add r0, r2, #27284; NEON-NEXT:    lsl r2, r6, #27285; NEON-NEXT:    orr r2, r2, r7, lsr #5286; NEON-NEXT:    mov r1, #31287; NEON-NEXT:    tst r0, #32288; NEON-NEXT:    mov r3, r5289; NEON-NEXT:    moveq r3, r2290; NEON-NEXT:    lsleq r2, r7, #27291; NEON-NEXT:    bic r1, r1, r0292; NEON-NEXT:    and r7, r0, #31293; NEON-NEXT:    lsl r6, r3, #1294; NEON-NEXT:    moveq r4, r5295; NEON-NEXT:    lsl r6, r6, r1296; NEON-NEXT:    orr r0, r6, r2, lsr r7297; NEON-NEXT:    lsl r2, r4, #1298; NEON-NEXT:    lsl r1, r2, r1299; NEON-NEXT:    orr r1, r1, r3, lsr r7300; NEON-NEXT:    pop {r4, r5, r6, r7, r11, pc}301  %f = call i37 @llvm.fshr.i37(i37 %x, i37 %y, i37 %z)302  ret i37 %f303}304 305; extract(concat(0b1110000, 0b1111111) >> 2) = 0b0011111306 307declare i7 @llvm.fshr.i7(i7, i7, i7)308define i7 @fshr_i7_const_fold() {309; CHECK-LABEL: fshr_i7_const_fold:310; CHECK:       @ %bb.0:311; CHECK-NEXT:    mov r0, #31312; CHECK-NEXT:    bx lr313  %f = call i7 @llvm.fshr.i7(i7 112, i7 127, i7 2)314  ret i7 %f315}316 317define i8 @fshr_i8_const_fold_overshift_1() {318; CHECK-LABEL: fshr_i8_const_fold_overshift_1:319; CHECK:       @ %bb.0:320; CHECK-NEXT:    mov r0, #254321; CHECK-NEXT:    bx lr322  %f = call i8 @llvm.fshr.i8(i8 255, i8 0, i8 15)323  ret i8 %f324}325 326define i8 @fshr_i8_const_fold_overshift_2() {327; CHECK-LABEL: fshr_i8_const_fold_overshift_2:328; CHECK:       @ %bb.0:329; CHECK-NEXT:    mov r0, #225330; CHECK-NEXT:    bx lr331  %f = call i8 @llvm.fshr.i8(i8 15, i8 15, i8 11)332  ret i8 %f333}334 335define i8 @fshr_i8_const_fold_overshift_3() {336; CHECK-LABEL: fshr_i8_const_fold_overshift_3:337; CHECK:       @ %bb.0:338; CHECK-NEXT:    mov r0, #255339; CHECK-NEXT:    bx lr340  %f = call i8 @llvm.fshr.i8(i8 0, i8 255, i8 8)341  ret i8 %f342}343 344; With constant shift amount, this is 'extr'.345 346define i32 @fshr_i32_const_shift(i32 %x, i32 %y) {347; CHECK-LABEL: fshr_i32_const_shift:348; CHECK:       @ %bb.0:349; CHECK-NEXT:    lsl r0, r0, #23350; CHECK-NEXT:    orr r0, r0, r1, lsr #9351; CHECK-NEXT:    bx lr352  %f = call i32 @llvm.fshr.i32(i32 %x, i32 %y, i32 9)353  ret i32 %f354}355 356; Check modulo math on shift amount. 41-32=9.357 358define i32 @fshr_i32_const_overshift(i32 %x, i32 %y) {359; CHECK-LABEL: fshr_i32_const_overshift:360; CHECK:       @ %bb.0:361; CHECK-NEXT:    lsl r0, r0, #23362; CHECK-NEXT:    orr r0, r0, r1, lsr #9363; CHECK-NEXT:    bx lr364  %f = call i32 @llvm.fshr.i32(i32 %x, i32 %y, i32 41)365  ret i32 %f366}367 368; 64-bit should also work. 105-64 = 41.369 370define i64 @fshr_i64_const_overshift(i64 %x, i64 %y) {371; CHECK-LABEL: fshr_i64_const_overshift:372; CHECK:       @ %bb.0:373; CHECK-NEXT:    lsl r2, r0, #23374; CHECK-NEXT:    lsl r1, r1, #23375; CHECK-NEXT:    orr r2, r2, r3, lsr #9376; CHECK-NEXT:    orr r1, r1, r0, lsr #9377; CHECK-NEXT:    mov r0, r2378; CHECK-NEXT:    bx lr379  %f = call i64 @llvm.fshr.i64(i64 %x, i64 %y, i64 105)380  ret i64 %f381}382 383; This should work without any node-specific logic.384 385define i8 @fshr_i8_const_fold() {386; CHECK-LABEL: fshr_i8_const_fold:387; CHECK:       @ %bb.0:388; CHECK-NEXT:    mov r0, #254389; CHECK-NEXT:    bx lr390  %f = call i8 @llvm.fshr.i8(i8 255, i8 0, i8 7)391  ret i8 %f392}393 394define i32 @fshl_i32_shift_by_bitwidth(i32 %x, i32 %y) {395; CHECK-LABEL: fshl_i32_shift_by_bitwidth:396; CHECK:       @ %bb.0:397; CHECK-NEXT:    bx lr398  %f = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 32)399  ret i32 %f400}401 402define i32 @fshr_i32_shift_by_bitwidth(i32 %x, i32 %y) {403; CHECK-LABEL: fshr_i32_shift_by_bitwidth:404; CHECK:       @ %bb.0:405; CHECK-NEXT:    mov r0, r1406; CHECK-NEXT:    bx lr407  %f = call i32 @llvm.fshr.i32(i32 %x, i32 %y, i32 32)408  ret i32 %f409}410 411define <4 x i32> @fshl_v4i32_shift_by_bitwidth(<4 x i32> %x, <4 x i32> %y) {412; CHECK-LABEL: fshl_v4i32_shift_by_bitwidth:413; CHECK:       @ %bb.0:414; CHECK-NEXT:    bx lr415  %f = call <4 x i32> @llvm.fshl.v4i32(<4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 32, i32 32, i32 32, i32 32>)416  ret <4 x i32> %f417}418 419define <4 x i32> @fshr_v4i32_shift_by_bitwidth(<4 x i32> %x, <4 x i32> %y) {420; SCALAR-LABEL: fshr_v4i32_shift_by_bitwidth:421; SCALAR:       @ %bb.0:422; SCALAR-NEXT:    ldm sp, {r0, r1, r2, r3}423; SCALAR-NEXT:    bx lr424;425; NEON-LABEL: fshr_v4i32_shift_by_bitwidth:426; NEON:       @ %bb.0:427; NEON-NEXT:    mov r0, sp428; NEON-NEXT:    vld1.64 {d16, d17}, [r0]429; NEON-NEXT:    vmov r0, r1, d16430; NEON-NEXT:    vmov r2, r3, d17431; NEON-NEXT:    bx lr432  %f = call <4 x i32> @llvm.fshr.v4i32(<4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 32, i32 32, i32 32, i32 32>)433  ret <4 x i32> %f434}435 436