brintos

brintos / llvm-project-archived public Read only

0
0
Text · 12.9 KiB · 8a21889 Raw
470 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -mtriple=riscv64 -global-isel -verify-machineinstrs < %s \3; RUN:   | FileCheck %s -check-prefixes=CHECK,RV64I4; RUN: llc -mtriple=riscv64 -global-isel -mattr=+zbb -verify-machineinstrs < %s \5; RUN:   | FileCheck %s -check-prefixes=CHECK,RV64ZBB-ZBKB,RV64ZBB6; RUN: llc -mtriple=riscv64 -global-isel -mattr=+zbkb -verify-machineinstrs < %s \7; RUN:   | FileCheck %s -check-prefixes=CHECK,RV64ZBB-ZBKB,RV64ZBKB8 9define signext i32 @andn_i32(i32 signext %a, i32 signext %b) nounwind {10; RV64I-LABEL: andn_i32:11; RV64I:       # %bb.0:12; RV64I-NEXT:    not a1, a113; RV64I-NEXT:    and a0, a1, a014; RV64I-NEXT:    ret15;16; RV64ZBB-ZBKB-LABEL: andn_i32:17; RV64ZBB-ZBKB:       # %bb.0:18; RV64ZBB-ZBKB-NEXT:    andn a0, a0, a119; RV64ZBB-ZBKB-NEXT:    ret20  %neg = xor i32 %b, -121  %and = and i32 %neg, %a22  ret i32 %and23}24 25define i64 @andn_i64(i64 %a, i64 %b) nounwind {26; RV64I-LABEL: andn_i64:27; RV64I:       # %bb.0:28; RV64I-NEXT:    not a1, a129; RV64I-NEXT:    and a0, a1, a030; RV64I-NEXT:    ret31;32; RV64ZBB-ZBKB-LABEL: andn_i64:33; RV64ZBB-ZBKB:       # %bb.0:34; RV64ZBB-ZBKB-NEXT:    andn a0, a0, a135; RV64ZBB-ZBKB-NEXT:    ret36  %neg = xor i64 %b, -137  %and = and i64 %neg, %a38  ret i64 %and39}40 41define signext i32 @orn_i32(i32 signext %a, i32 signext %b) nounwind {42; RV64I-LABEL: orn_i32:43; RV64I:       # %bb.0:44; RV64I-NEXT:    not a1, a145; RV64I-NEXT:    or a0, a1, a046; RV64I-NEXT:    ret47;48; RV64ZBB-ZBKB-LABEL: orn_i32:49; RV64ZBB-ZBKB:       # %bb.0:50; RV64ZBB-ZBKB-NEXT:    orn a0, a0, a151; RV64ZBB-ZBKB-NEXT:    ret52  %neg = xor i32 %b, -153  %or = or i32 %neg, %a54  ret i32 %or55}56 57define i64 @orn_i64(i64 %a, i64 %b) nounwind {58; RV64I-LABEL: orn_i64:59; RV64I:       # %bb.0:60; RV64I-NEXT:    not a1, a161; RV64I-NEXT:    or a0, a1, a062; RV64I-NEXT:    ret63;64; RV64ZBB-ZBKB-LABEL: orn_i64:65; RV64ZBB-ZBKB:       # %bb.0:66; RV64ZBB-ZBKB-NEXT:    orn a0, a0, a167; RV64ZBB-ZBKB-NEXT:    ret68  %neg = xor i64 %b, -169  %or = or i64 %neg, %a70  ret i64 %or71}72 73define signext i32 @xnor_i32(i32 signext %a, i32 signext %b) nounwind {74; RV64I-LABEL: xnor_i32:75; RV64I:       # %bb.0:76; RV64I-NEXT:    not a0, a077; RV64I-NEXT:    xor a0, a0, a178; RV64I-NEXT:    ret79;80; RV64ZBB-ZBKB-LABEL: xnor_i32:81; RV64ZBB-ZBKB:       # %bb.0:82; RV64ZBB-ZBKB-NEXT:    xnor a0, a0, a183; RV64ZBB-ZBKB-NEXT:    ret84  %neg = xor i32 %a, -185  %xor = xor i32 %neg, %b86  ret i32 %xor87}88 89define i64 @xnor_i64(i64 %a, i64 %b) nounwind {90; RV64I-LABEL: xnor_i64:91; RV64I:       # %bb.0:92; RV64I-NEXT:    not a0, a093; RV64I-NEXT:    xor a0, a0, a194; RV64I-NEXT:    ret95;96; RV64ZBB-ZBKB-LABEL: xnor_i64:97; RV64ZBB-ZBKB:       # %bb.0:98; RV64ZBB-ZBKB-NEXT:    xnor a0, a0, a199; RV64ZBB-ZBKB-NEXT:    ret100  %neg = xor i64 %a, -1101  %xor = xor i64 %neg, %b102  ret i64 %xor103}104 105define signext i32 @rol_i32(i32 signext %a, i32 signext %b) nounwind {106; RV64I-LABEL: rol_i32:107; RV64I:       # %bb.0:108; RV64I-NEXT:    neg a2, a1109; RV64I-NEXT:    sllw a1, a0, a1110; RV64I-NEXT:    srlw a0, a0, a2111; RV64I-NEXT:    or a0, a1, a0112; RV64I-NEXT:    ret113;114; RV64ZBB-ZBKB-LABEL: rol_i32:115; RV64ZBB-ZBKB:       # %bb.0:116; RV64ZBB-ZBKB-NEXT:    rolw a0, a0, a1117; RV64ZBB-ZBKB-NEXT:    ret118  %1 = tail call i32 @llvm.fshl.i32(i32 %a, i32 %a, i32 %b)119  ret i32 %1120}121 122; Similar to rol_i32, but doesn't sign extend the result.123define void @rol_i32_nosext(i32 signext %a, i32 signext %b, ptr %x) nounwind {124; RV64I-LABEL: rol_i32_nosext:125; RV64I:       # %bb.0:126; RV64I-NEXT:    neg a3, a1127; RV64I-NEXT:    sllw a1, a0, a1128; RV64I-NEXT:    srlw a0, a0, a3129; RV64I-NEXT:    or a0, a1, a0130; RV64I-NEXT:    sw a0, 0(a2)131; RV64I-NEXT:    ret132;133; RV64ZBB-ZBKB-LABEL: rol_i32_nosext:134; RV64ZBB-ZBKB:       # %bb.0:135; RV64ZBB-ZBKB-NEXT:    rolw a0, a0, a1136; RV64ZBB-ZBKB-NEXT:    sw a0, 0(a2)137; RV64ZBB-ZBKB-NEXT:    ret138  %1 = tail call i32 @llvm.fshl.i32(i32 %a, i32 %a, i32 %b)139  store i32 %1, ptr %x140  ret void141}142 143define signext i32 @rol_i32_neg_constant_rhs(i32 signext %a) nounwind {144; RV64I-LABEL: rol_i32_neg_constant_rhs:145; RV64I:       # %bb.0:146; RV64I-NEXT:    li a1, -2147; RV64I-NEXT:    neg a2, a0148; RV64I-NEXT:    sllw a0, a1, a0149; RV64I-NEXT:    srlw a1, a1, a2150; RV64I-NEXT:    or a0, a0, a1151; RV64I-NEXT:    ret152;153; RV64ZBB-ZBKB-LABEL: rol_i32_neg_constant_rhs:154; RV64ZBB-ZBKB:       # %bb.0:155; RV64ZBB-ZBKB-NEXT:    li a1, -2156; RV64ZBB-ZBKB-NEXT:    rolw a0, a1, a0157; RV64ZBB-ZBKB-NEXT:    ret158  %1 = tail call i32 @llvm.fshl.i32(i32 -2, i32 -2, i32 %a)159  ret i32 %1160}161 162define i64 @rol_i64(i64 %a, i64 %b) nounwind {163; RV64I-LABEL: rol_i64:164; RV64I:       # %bb.0:165; RV64I-NEXT:    neg a2, a1166; RV64I-NEXT:    sll a1, a0, a1167; RV64I-NEXT:    srl a0, a0, a2168; RV64I-NEXT:    or a0, a1, a0169; RV64I-NEXT:    ret170;171; RV64ZBB-ZBKB-LABEL: rol_i64:172; RV64ZBB-ZBKB:       # %bb.0:173; RV64ZBB-ZBKB-NEXT:    rol a0, a0, a1174; RV64ZBB-ZBKB-NEXT:    ret175  %or = tail call i64 @llvm.fshl.i64(i64 %a, i64 %a, i64 %b)176  ret i64 %or177}178 179define signext i32 @ror_i32(i32 signext %a, i32 signext %b) nounwind {180; RV64I-LABEL: ror_i32:181; RV64I:       # %bb.0:182; RV64I-NEXT:    neg a2, a1183; RV64I-NEXT:    srlw a1, a0, a1184; RV64I-NEXT:    sllw a0, a0, a2185; RV64I-NEXT:    or a0, a1, a0186; RV64I-NEXT:    ret187;188; RV64ZBB-ZBKB-LABEL: ror_i32:189; RV64ZBB-ZBKB:       # %bb.0:190; RV64ZBB-ZBKB-NEXT:    rorw a0, a0, a1191; RV64ZBB-ZBKB-NEXT:    ret192  %1 = tail call i32 @llvm.fshr.i32(i32 %a, i32 %a, i32 %b)193  ret i32 %1194}195 196; Similar to ror_i32, but doesn't sign extend the result.197define void @ror_i32_nosext(i32 signext %a, i32 signext %b, ptr %x) nounwind {198; RV64I-LABEL: ror_i32_nosext:199; RV64I:       # %bb.0:200; RV64I-NEXT:    neg a3, a1201; RV64I-NEXT:    srlw a1, a0, a1202; RV64I-NEXT:    sllw a0, a0, a3203; RV64I-NEXT:    or a0, a1, a0204; RV64I-NEXT:    sw a0, 0(a2)205; RV64I-NEXT:    ret206;207; RV64ZBB-ZBKB-LABEL: ror_i32_nosext:208; RV64ZBB-ZBKB:       # %bb.0:209; RV64ZBB-ZBKB-NEXT:    rorw a0, a0, a1210; RV64ZBB-ZBKB-NEXT:    sw a0, 0(a2)211; RV64ZBB-ZBKB-NEXT:    ret212  %1 = tail call i32 @llvm.fshr.i32(i32 %a, i32 %a, i32 %b)213  store i32 %1, ptr %x214  ret void215}216 217define signext i32 @ror_i32_neg_constant_rhs(i32 signext %a) nounwind {218; RV64I-LABEL: ror_i32_neg_constant_rhs:219; RV64I:       # %bb.0:220; RV64I-NEXT:    li a1, -2221; RV64I-NEXT:    neg a2, a0222; RV64I-NEXT:    srlw a0, a1, a0223; RV64I-NEXT:    sllw a1, a1, a2224; RV64I-NEXT:    or a0, a0, a1225; RV64I-NEXT:    ret226;227; RV64ZBB-ZBKB-LABEL: ror_i32_neg_constant_rhs:228; RV64ZBB-ZBKB:       # %bb.0:229; RV64ZBB-ZBKB-NEXT:    li a1, -2230; RV64ZBB-ZBKB-NEXT:    rorw a0, a1, a0231; RV64ZBB-ZBKB-NEXT:    ret232  %1 = tail call i32 @llvm.fshr.i32(i32 -2, i32 -2, i32 %a)233  ret i32 %1234}235 236define i64 @ror_i64(i64 %a, i64 %b) nounwind {237; RV64I-LABEL: ror_i64:238; RV64I:       # %bb.0:239; RV64I-NEXT:    neg a2, a1240; RV64I-NEXT:    srl a1, a0, a1241; RV64I-NEXT:    sll a0, a0, a2242; RV64I-NEXT:    or a0, a1, a0243; RV64I-NEXT:    ret244;245; RV64ZBB-ZBKB-LABEL: ror_i64:246; RV64ZBB-ZBKB:       # %bb.0:247; RV64ZBB-ZBKB-NEXT:    ror a0, a0, a1248; RV64ZBB-ZBKB-NEXT:    ret249  %or = tail call i64 @llvm.fshr.i64(i64 %a, i64 %a, i64 %b)250  ret i64 %or251}252 253define signext i32 @rori_i32_fshl(i32 signext %a) nounwind {254; RV64I-LABEL: rori_i32_fshl:255; RV64I:       # %bb.0:256; RV64I-NEXT:    slliw a1, a0, 31257; RV64I-NEXT:    srliw a0, a0, 1258; RV64I-NEXT:    or a0, a1, a0259; RV64I-NEXT:    ret260;261; RV64ZBB-ZBKB-LABEL: rori_i32_fshl:262; RV64ZBB-ZBKB:       # %bb.0:263; RV64ZBB-ZBKB-NEXT:    roriw a0, a0, 1264; RV64ZBB-ZBKB-NEXT:    ret265  %1 = tail call i32 @llvm.fshl.i32(i32 %a, i32 %a, i32 31)266  ret i32 %1267}268 269; Similar to rori_i32_fshl, but doesn't sign extend the result.270define void @rori_i32_fshl_nosext(i32 signext %a, ptr %x) nounwind {271; RV64I-LABEL: rori_i32_fshl_nosext:272; RV64I:       # %bb.0:273; RV64I-NEXT:    slli a2, a0, 31274; RV64I-NEXT:    srliw a0, a0, 1275; RV64I-NEXT:    or a0, a2, a0276; RV64I-NEXT:    sw a0, 0(a1)277; RV64I-NEXT:    ret278;279; RV64ZBB-ZBKB-LABEL: rori_i32_fshl_nosext:280; RV64ZBB-ZBKB:       # %bb.0:281; RV64ZBB-ZBKB-NEXT:    roriw a0, a0, 1282; RV64ZBB-ZBKB-NEXT:    sw a0, 0(a1)283; RV64ZBB-ZBKB-NEXT:    ret284  %1 = tail call i32 @llvm.fshl.i32(i32 %a, i32 %a, i32 31)285  store i32 %1, ptr %x286  ret void287}288 289define signext i32 @rori_i32_fshr(i32 signext %a) nounwind {290; RV64I-LABEL: rori_i32_fshr:291; RV64I:       # %bb.0:292; RV64I-NEXT:    srliw a1, a0, 31293; RV64I-NEXT:    slliw a0, a0, 1294; RV64I-NEXT:    or a0, a1, a0295; RV64I-NEXT:    ret296;297; RV64ZBB-ZBKB-LABEL: rori_i32_fshr:298; RV64ZBB-ZBKB:       # %bb.0:299; RV64ZBB-ZBKB-NEXT:    roriw a0, a0, 31300; RV64ZBB-ZBKB-NEXT:    ret301  %1 = tail call i32 @llvm.fshr.i32(i32 %a, i32 %a, i32 31)302  ret i32 %1303}304 305; Similar to rori_i32_fshr, but doesn't sign extend the result.306define void @rori_i32_fshr_nosext(i32 signext %a, ptr %x) nounwind {307; RV64I-LABEL: rori_i32_fshr_nosext:308; RV64I:       # %bb.0:309; RV64I-NEXT:    srliw a2, a0, 31310; RV64I-NEXT:    slli a0, a0, 1311; RV64I-NEXT:    or a0, a2, a0312; RV64I-NEXT:    sw a0, 0(a1)313; RV64I-NEXT:    ret314;315; RV64ZBB-ZBKB-LABEL: rori_i32_fshr_nosext:316; RV64ZBB-ZBKB:       # %bb.0:317; RV64ZBB-ZBKB-NEXT:    roriw a0, a0, 31318; RV64ZBB-ZBKB-NEXT:    sw a0, 0(a1)319; RV64ZBB-ZBKB-NEXT:    ret320  %1 = tail call i32 @llvm.fshr.i32(i32 %a, i32 %a, i32 31)321  store i32 %1, ptr %x322  ret void323}324 325; This test is similar to the type legalized version of the fshl/fshr tests, but326; instead of having the same input to both shifts it has different inputs. Make327; sure we don't match it as a roriw.328define signext i32 @not_rori_i32(i32 signext %x, i32 signext %y) nounwind {329; CHECK-LABEL: not_rori_i32:330; CHECK:       # %bb.0:331; CHECK-NEXT:    slliw a0, a0, 31332; CHECK-NEXT:    srliw a1, a1, 1333; CHECK-NEXT:    or a0, a0, a1334; CHECK-NEXT:    ret335  %a = shl i32 %x, 31336  %b = lshr i32 %y, 1337  %c = or i32 %a, %b338  ret i32 %c339}340 341; This is similar to the type legalized roriw pattern, but the and mask is more342; than 32 bits so the lshr doesn't shift zeroes into the lower 32 bits. Make343; sure we don't match it to roriw.344define i64 @roriw_bug(i64 %x) nounwind {345; CHECK-LABEL: roriw_bug:346; CHECK:       # %bb.0:347; CHECK-NEXT:    andi a1, a0, -2348; CHECK-NEXT:    srli a2, a1, 1349; CHECK-NEXT:    slli a0, a0, 63350; CHECK-NEXT:    slli a2, a2, 32351; CHECK-NEXT:    or a0, a0, a2352; CHECK-NEXT:    srai a0, a0, 32353; CHECK-NEXT:    xor a0, a1, a0354; CHECK-NEXT:    ret355  %a = shl i64 %x, 31356  %b = and i64 %x, 18446744073709551614357  %c = lshr i64 %b, 1358  %d = or i64 %a, %c359  %e = shl i64 %d, 32360  %f = ashr i64 %e, 32361  %g = xor i64 %b, %f ; to increase the use count on %b to disable SimplifyDemandedBits.362  ret i64 %g363}364 365define i64 @rori_i64_fshl(i64 %a) nounwind {366; RV64I-LABEL: rori_i64_fshl:367; RV64I:       # %bb.0:368; RV64I-NEXT:    slli a1, a0, 63369; RV64I-NEXT:    srli a0, a0, 1370; RV64I-NEXT:    or a0, a1, a0371; RV64I-NEXT:    ret372;373; RV64ZBB-ZBKB-LABEL: rori_i64_fshl:374; RV64ZBB-ZBKB:       # %bb.0:375; RV64ZBB-ZBKB-NEXT:    rori a0, a0, 1376; RV64ZBB-ZBKB-NEXT:    ret377  %1 = tail call i64 @llvm.fshl.i64(i64 %a, i64 %a, i64 63)378  ret i64 %1379}380 381define i64 @rori_i64_fshr(i64 %a) nounwind {382; RV64I-LABEL: rori_i64_fshr:383; RV64I:       # %bb.0:384; RV64I-NEXT:    srli a1, a0, 63385; RV64I-NEXT:    slli a0, a0, 1386; RV64I-NEXT:    or a0, a1, a0387; RV64I-NEXT:    ret388;389; RV64ZBB-ZBKB-LABEL: rori_i64_fshr:390; RV64ZBB-ZBKB:       # %bb.0:391; RV64ZBB-ZBKB-NEXT:    rori a0, a0, 63392; RV64ZBB-ZBKB-NEXT:    ret393  %1 = tail call i64 @llvm.fshr.i64(i64 %a, i64 %a, i64 63)394  ret i64 %1395}396 397define i8 @srli_i8(i8 %a) nounwind {398; CHECK-LABEL: srli_i8:399; CHECK:       # %bb.0:400; CHECK-NEXT:    zext.b a0, a0401; CHECK-NEXT:    srli a0, a0, 6402; CHECK-NEXT:    ret403  %1 = lshr i8 %a, 6404  ret i8 %1405}406 407; FIXME: We should use slli+srai with Zbb for better compression.408define i8 @srai_i8(i8 %a) nounwind {409; RV64I-LABEL: srai_i8:410; RV64I:       # %bb.0:411; RV64I-NEXT:    slli a0, a0, 56412; RV64I-NEXT:    srai a0, a0, 61413; RV64I-NEXT:    ret414;415; RV64ZBB-LABEL: srai_i8:416; RV64ZBB:       # %bb.0:417; RV64ZBB-NEXT:    sext.b a0, a0418; RV64ZBB-NEXT:    srai a0, a0, 5419; RV64ZBB-NEXT:    ret420;421; RV64ZBKB-LABEL: srai_i8:422; RV64ZBKB:       # %bb.0:423; RV64ZBKB-NEXT:    slli a0, a0, 56424; RV64ZBKB-NEXT:    srai a0, a0, 61425; RV64ZBKB-NEXT:    ret426  %1 = ashr i8 %a, 5427  ret i8 %1428}429 430; FIXME: We should use slli+srli.431define i16 @srli_i16(i16 %a) nounwind {432; RV64I-LABEL: srli_i16:433; RV64I:       # %bb.0:434; RV64I-NEXT:    slli a0, a0, 48435; RV64I-NEXT:    srli a0, a0, 48436; RV64I-NEXT:    srli a0, a0, 6437; RV64I-NEXT:    ret438;439; RV64ZBB-ZBKB-LABEL: srli_i16:440; RV64ZBB-ZBKB:       # %bb.0:441; RV64ZBB-ZBKB-NEXT:    zext.h a0, a0442; RV64ZBB-ZBKB-NEXT:    srli a0, a0, 6443; RV64ZBB-ZBKB-NEXT:    ret444  %1 = lshr i16 %a, 6445  ret i16 %1446}447 448; FIXME: We should use slli+srai with Zbb for better compression.449define i16 @srai_i16(i16 %a) nounwind {450; RV64I-LABEL: srai_i16:451; RV64I:       # %bb.0:452; RV64I-NEXT:    slli a0, a0, 48453; RV64I-NEXT:    srai a0, a0, 57454; RV64I-NEXT:    ret455;456; RV64ZBB-LABEL: srai_i16:457; RV64ZBB:       # %bb.0:458; RV64ZBB-NEXT:    sext.h a0, a0459; RV64ZBB-NEXT:    srai a0, a0, 9460; RV64ZBB-NEXT:    ret461;462; RV64ZBKB-LABEL: srai_i16:463; RV64ZBKB:       # %bb.0:464; RV64ZBKB-NEXT:    slli a0, a0, 48465; RV64ZBKB-NEXT:    srai a0, a0, 57466; RV64ZBKB-NEXT:    ret467  %1 = ashr i16 %a, 9468  ret i16 %1469}470