623 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc --mtriple=loongarch32 -mattr=-32s,+d < %s | FileCheck %s --check-prefix=LA32R3; RUN: llc --mtriple=loongarch32 -mattr=+32s,+d < %s | FileCheck %s --check-prefix=LA32S4; RUN: llc --mtriple=loongarch64 -mattr=+d < %s | FileCheck %s --check-prefix=LA645 6;; Exercise the 'and' LLVM IR: https://llvm.org/docs/LangRef.html#and-instruction7 8define i1 @and_i1(i1 %a, i1 %b) {9; LA32R-LABEL: and_i1:10; LA32R: # %bb.0: # %entry11; LA32R-NEXT: and $a0, $a0, $a112; LA32R-NEXT: ret13;14; LA32S-LABEL: and_i1:15; LA32S: # %bb.0: # %entry16; LA32S-NEXT: and $a0, $a0, $a117; LA32S-NEXT: ret18;19; LA64-LABEL: and_i1:20; LA64: # %bb.0: # %entry21; LA64-NEXT: and $a0, $a0, $a122; LA64-NEXT: ret23entry:24 %r = and i1 %a, %b25 ret i1 %r26}27 28define i8 @and_i8(i8 %a, i8 %b) {29; LA32R-LABEL: and_i8:30; LA32R: # %bb.0: # %entry31; LA32R-NEXT: and $a0, $a0, $a132; LA32R-NEXT: ret33;34; LA32S-LABEL: and_i8:35; LA32S: # %bb.0: # %entry36; LA32S-NEXT: and $a0, $a0, $a137; LA32S-NEXT: ret38;39; LA64-LABEL: and_i8:40; LA64: # %bb.0: # %entry41; LA64-NEXT: and $a0, $a0, $a142; LA64-NEXT: ret43entry:44 %r = and i8 %a, %b45 ret i8 %r46}47 48define i16 @and_i16(i16 %a, i16 %b) {49; LA32R-LABEL: and_i16:50; LA32R: # %bb.0: # %entry51; LA32R-NEXT: and $a0, $a0, $a152; LA32R-NEXT: ret53;54; LA32S-LABEL: and_i16:55; LA32S: # %bb.0: # %entry56; LA32S-NEXT: and $a0, $a0, $a157; LA32S-NEXT: ret58;59; LA64-LABEL: and_i16:60; LA64: # %bb.0: # %entry61; LA64-NEXT: and $a0, $a0, $a162; LA64-NEXT: ret63entry:64 %r = and i16 %a, %b65 ret i16 %r66}67 68define i32 @and_i32(i32 %a, i32 %b) {69; LA32R-LABEL: and_i32:70; LA32R: # %bb.0: # %entry71; LA32R-NEXT: and $a0, $a0, $a172; LA32R-NEXT: ret73;74; LA32S-LABEL: and_i32:75; LA32S: # %bb.0: # %entry76; LA32S-NEXT: and $a0, $a0, $a177; LA32S-NEXT: ret78;79; LA64-LABEL: and_i32:80; LA64: # %bb.0: # %entry81; LA64-NEXT: and $a0, $a0, $a182; LA64-NEXT: ret83entry:84 %r = and i32 %a, %b85 ret i32 %r86}87 88define i64 @and_i64(i64 %a, i64 %b) {89; LA32R-LABEL: and_i64:90; LA32R: # %bb.0: # %entry91; LA32R-NEXT: and $a0, $a0, $a292; LA32R-NEXT: and $a1, $a1, $a393; LA32R-NEXT: ret94;95; LA32S-LABEL: and_i64:96; LA32S: # %bb.0: # %entry97; LA32S-NEXT: and $a0, $a0, $a298; LA32S-NEXT: and $a1, $a1, $a399; LA32S-NEXT: ret100;101; LA64-LABEL: and_i64:102; LA64: # %bb.0: # %entry103; LA64-NEXT: and $a0, $a0, $a1104; LA64-NEXT: ret105entry:106 %r = and i64 %a, %b107 ret i64 %r108}109 110define i1 @and_i1_0(i1 %b) {111; LA32R-LABEL: and_i1_0:112; LA32R: # %bb.0: # %entry113; LA32R-NEXT: move $a0, $zero114; LA32R-NEXT: ret115;116; LA32S-LABEL: and_i1_0:117; LA32S: # %bb.0: # %entry118; LA32S-NEXT: move $a0, $zero119; LA32S-NEXT: ret120;121; LA64-LABEL: and_i1_0:122; LA64: # %bb.0: # %entry123; LA64-NEXT: move $a0, $zero124; LA64-NEXT: ret125entry:126 %r = and i1 4, %b127 ret i1 %r128}129 130define i1 @and_i1_5(i1 %b) {131; LA32R-LABEL: and_i1_5:132; LA32R: # %bb.0: # %entry133; LA32R-NEXT: ret134;135; LA32S-LABEL: and_i1_5:136; LA32S: # %bb.0: # %entry137; LA32S-NEXT: ret138;139; LA64-LABEL: and_i1_5:140; LA64: # %bb.0: # %entry141; LA64-NEXT: ret142entry:143 %r = and i1 5, %b144 ret i1 %r145}146 147define i8 @and_i8_5(i8 %b) {148; LA32R-LABEL: and_i8_5:149; LA32R: # %bb.0: # %entry150; LA32R-NEXT: andi $a0, $a0, 5151; LA32R-NEXT: ret152;153; LA32S-LABEL: and_i8_5:154; LA32S: # %bb.0: # %entry155; LA32S-NEXT: andi $a0, $a0, 5156; LA32S-NEXT: ret157;158; LA64-LABEL: and_i8_5:159; LA64: # %bb.0: # %entry160; LA64-NEXT: andi $a0, $a0, 5161; LA64-NEXT: ret162entry:163 %r = and i8 5, %b164 ret i8 %r165}166 167define i8 @and_i8_257(i8 %b) {168; LA32R-LABEL: and_i8_257:169; LA32R: # %bb.0: # %entry170; LA32R-NEXT: andi $a0, $a0, 1171; LA32R-NEXT: ret172;173; LA32S-LABEL: and_i8_257:174; LA32S: # %bb.0: # %entry175; LA32S-NEXT: andi $a0, $a0, 1176; LA32S-NEXT: ret177;178; LA64-LABEL: and_i8_257:179; LA64: # %bb.0: # %entry180; LA64-NEXT: andi $a0, $a0, 1181; LA64-NEXT: ret182entry:183 %r = and i8 257, %b184 ret i8 %r185}186 187define i16 @and_i16_5(i16 %b) {188; LA32R-LABEL: and_i16_5:189; LA32R: # %bb.0: # %entry190; LA32R-NEXT: andi $a0, $a0, 5191; LA32R-NEXT: ret192;193; LA32S-LABEL: and_i16_5:194; LA32S: # %bb.0: # %entry195; LA32S-NEXT: andi $a0, $a0, 5196; LA32S-NEXT: ret197;198; LA64-LABEL: and_i16_5:199; LA64: # %bb.0: # %entry200; LA64-NEXT: andi $a0, $a0, 5201; LA64-NEXT: ret202entry:203 %r = and i16 5, %b204 ret i16 %r205}206 207define i16 @and_i16_0x1000(i16 %b) {208; LA32R-LABEL: and_i16_0x1000:209; LA32R: # %bb.0: # %entry210; LA32R-NEXT: lu12i.w $a1, 1211; LA32R-NEXT: and $a0, $a0, $a1212; LA32R-NEXT: ret213;214; LA32S-LABEL: and_i16_0x1000:215; LA32S: # %bb.0: # %entry216; LA32S-NEXT: lu12i.w $a1, 1217; LA32S-NEXT: and $a0, $a0, $a1218; LA32S-NEXT: ret219;220; LA64-LABEL: and_i16_0x1000:221; LA64: # %bb.0: # %entry222; LA64-NEXT: lu12i.w $a1, 1223; LA64-NEXT: and $a0, $a0, $a1224; LA64-NEXT: ret225entry:226 %r = and i16 4096, %b227 ret i16 %r228}229 230define i16 @and_i16_0x10001(i16 %b) {231; LA32R-LABEL: and_i16_0x10001:232; LA32R: # %bb.0: # %entry233; LA32R-NEXT: andi $a0, $a0, 1234; LA32R-NEXT: ret235;236; LA32S-LABEL: and_i16_0x10001:237; LA32S: # %bb.0: # %entry238; LA32S-NEXT: andi $a0, $a0, 1239; LA32S-NEXT: ret240;241; LA64-LABEL: and_i16_0x10001:242; LA64: # %bb.0: # %entry243; LA64-NEXT: andi $a0, $a0, 1244; LA64-NEXT: ret245entry:246 %r = and i16 65537, %b247 ret i16 %r248}249 250define i32 @and_i32_5(i32 %b) {251; LA32R-LABEL: and_i32_5:252; LA32R: # %bb.0: # %entry253; LA32R-NEXT: andi $a0, $a0, 5254; LA32R-NEXT: ret255;256; LA32S-LABEL: and_i32_5:257; LA32S: # %bb.0: # %entry258; LA32S-NEXT: andi $a0, $a0, 5259; LA32S-NEXT: ret260;261; LA64-LABEL: and_i32_5:262; LA64: # %bb.0: # %entry263; LA64-NEXT: andi $a0, $a0, 5264; LA64-NEXT: ret265entry:266 %r = and i32 5, %b267 ret i32 %r268}269 270define i32 @and_i32_0x1000(i32 %b) {271; LA32R-LABEL: and_i32_0x1000:272; LA32R: # %bb.0: # %entry273; LA32R-NEXT: lu12i.w $a1, 1274; LA32R-NEXT: and $a0, $a0, $a1275; LA32R-NEXT: ret276;277; LA32S-LABEL: and_i32_0x1000:278; LA32S: # %bb.0: # %entry279; LA32S-NEXT: lu12i.w $a1, 1280; LA32S-NEXT: and $a0, $a0, $a1281; LA32S-NEXT: ret282;283; LA64-LABEL: and_i32_0x1000:284; LA64: # %bb.0: # %entry285; LA64-NEXT: lu12i.w $a1, 1286; LA64-NEXT: and $a0, $a0, $a1287; LA64-NEXT: ret288entry:289 %r = and i32 4096, %b290 ret i32 %r291}292 293define i32 @and_i32_0x100000001(i32 %b) {294; LA32R-LABEL: and_i32_0x100000001:295; LA32R: # %bb.0: # %entry296; LA32R-NEXT: andi $a0, $a0, 1297; LA32R-NEXT: ret298;299; LA32S-LABEL: and_i32_0x100000001:300; LA32S: # %bb.0: # %entry301; LA32S-NEXT: andi $a0, $a0, 1302; LA32S-NEXT: ret303;304; LA64-LABEL: and_i32_0x100000001:305; LA64: # %bb.0: # %entry306; LA64-NEXT: andi $a0, $a0, 1307; LA64-NEXT: ret308entry:309 %r = and i32 4294967297, %b310 ret i32 %r311}312 313define i64 @and_i64_5(i64 %b) {314; LA32R-LABEL: and_i64_5:315; LA32R: # %bb.0: # %entry316; LA32R-NEXT: andi $a0, $a0, 5317; LA32R-NEXT: move $a1, $zero318; LA32R-NEXT: ret319;320; LA32S-LABEL: and_i64_5:321; LA32S: # %bb.0: # %entry322; LA32S-NEXT: andi $a0, $a0, 5323; LA32S-NEXT: move $a1, $zero324; LA32S-NEXT: ret325;326; LA64-LABEL: and_i64_5:327; LA64: # %bb.0: # %entry328; LA64-NEXT: andi $a0, $a0, 5329; LA64-NEXT: ret330entry:331 %r = and i64 5, %b332 ret i64 %r333}334 335define i64 @and_i64_0x1000(i64 %b) {336; LA32R-LABEL: and_i64_0x1000:337; LA32R: # %bb.0: # %entry338; LA32R-NEXT: lu12i.w $a1, 1339; LA32R-NEXT: and $a0, $a0, $a1340; LA32R-NEXT: move $a1, $zero341; LA32R-NEXT: ret342;343; LA32S-LABEL: and_i64_0x1000:344; LA32S: # %bb.0: # %entry345; LA32S-NEXT: lu12i.w $a1, 1346; LA32S-NEXT: and $a0, $a0, $a1347; LA32S-NEXT: move $a1, $zero348; LA32S-NEXT: ret349;350; LA64-LABEL: and_i64_0x1000:351; LA64: # %bb.0: # %entry352; LA64-NEXT: lu12i.w $a1, 1353; LA64-NEXT: and $a0, $a0, $a1354; LA64-NEXT: ret355entry:356 %r = and i64 4096, %b357 ret i64 %r358}359 360define signext i32 @and_i32_0xfff0(i32 %a) {361; LA32R-LABEL: and_i32_0xfff0:362; LA32R: # %bb.0:363; LA32R-NEXT: lu12i.w $a1, 15364; LA32R-NEXT: ori $a1, $a1, 4080365; LA32R-NEXT: and $a0, $a0, $a1366; LA32R-NEXT: ret367;368; LA32S-LABEL: and_i32_0xfff0:369; LA32S: # %bb.0:370; LA32S-NEXT: bstrpick.w $a0, $a0, 15, 4371; LA32S-NEXT: slli.w $a0, $a0, 4372; LA32S-NEXT: ret373;374; LA64-LABEL: and_i32_0xfff0:375; LA64: # %bb.0:376; LA64-NEXT: bstrpick.d $a0, $a0, 15, 4377; LA64-NEXT: slli.d $a0, $a0, 4378; LA64-NEXT: ret379 %b = and i32 %a, 65520380 ret i32 %b381}382 383define signext i32 @and_i32_0xfff0_twice(i32 %a, i32 %b) {384; LA32R-LABEL: and_i32_0xfff0_twice:385; LA32R: # %bb.0:386; LA32R-NEXT: lu12i.w $a2, 15387; LA32R-NEXT: ori $a2, $a2, 4080388; LA32R-NEXT: and $a0, $a0, $a2389; LA32R-NEXT: and $a1, $a1, $a2390; LA32R-NEXT: sub.w $a0, $a0, $a1391; LA32R-NEXT: ret392;393; LA32S-LABEL: and_i32_0xfff0_twice:394; LA32S: # %bb.0:395; LA32S-NEXT: bstrpick.w $a0, $a0, 15, 4396; LA32S-NEXT: slli.w $a0, $a0, 4397; LA32S-NEXT: bstrpick.w $a1, $a1, 15, 4398; LA32S-NEXT: slli.w $a1, $a1, 4399; LA32S-NEXT: sub.w $a0, $a0, $a1400; LA32S-NEXT: ret401;402; LA64-LABEL: and_i32_0xfff0_twice:403; LA64: # %bb.0:404; LA64-NEXT: bstrpick.d $a0, $a0, 15, 4405; LA64-NEXT: slli.d $a0, $a0, 4406; LA64-NEXT: bstrpick.d $a1, $a1, 15, 4407; LA64-NEXT: slli.d $a1, $a1, 4408; LA64-NEXT: sub.d $a0, $a0, $a1409; LA64-NEXT: ret410 %c = and i32 %a, 65520411 %d = and i32 %b, 65520412 %e = sub i32 %c, %d413 ret i32 %e414}415 416define i64 @and_i64_0xfff0(i64 %a) {417; LA32R-LABEL: and_i64_0xfff0:418; LA32R: # %bb.0:419; LA32R-NEXT: lu12i.w $a1, 15420; LA32R-NEXT: ori $a1, $a1, 4080421; LA32R-NEXT: and $a0, $a0, $a1422; LA32R-NEXT: move $a1, $zero423; LA32R-NEXT: ret424;425; LA32S-LABEL: and_i64_0xfff0:426; LA32S: # %bb.0:427; LA32S-NEXT: bstrpick.w $a0, $a0, 15, 4428; LA32S-NEXT: slli.w $a0, $a0, 4429; LA32S-NEXT: move $a1, $zero430; LA32S-NEXT: ret431;432; LA64-LABEL: and_i64_0xfff0:433; LA64: # %bb.0:434; LA64-NEXT: bstrpick.d $a0, $a0, 15, 4435; LA64-NEXT: slli.d $a0, $a0, 4436; LA64-NEXT: ret437 %b = and i64 %a, 65520438 ret i64 %b439}440 441define i64 @and_i64_0xfff0_twice(i64 %a, i64 %b) {442; LA32R-LABEL: and_i64_0xfff0_twice:443; LA32R: # %bb.0:444; LA32R-NEXT: lu12i.w $a1, 15445; LA32R-NEXT: ori $a1, $a1, 4080446; LA32R-NEXT: and $a3, $a0, $a1447; LA32R-NEXT: and $a1, $a2, $a1448; LA32R-NEXT: sub.w $a0, $a3, $a1449; LA32R-NEXT: sltu $a1, $a3, $a1450; LA32R-NEXT: sub.w $a1, $zero, $a1451; LA32R-NEXT: ret452;453; LA32S-LABEL: and_i64_0xfff0_twice:454; LA32S: # %bb.0:455; LA32S-NEXT: bstrpick.w $a0, $a0, 15, 4456; LA32S-NEXT: slli.w $a1, $a0, 4457; LA32S-NEXT: bstrpick.w $a0, $a2, 15, 4458; LA32S-NEXT: slli.w $a2, $a0, 4459; LA32S-NEXT: sub.w $a0, $a1, $a2460; LA32S-NEXT: sltu $a1, $a1, $a2461; LA32S-NEXT: sub.w $a1, $zero, $a1462; LA32S-NEXT: ret463;464; LA64-LABEL: and_i64_0xfff0_twice:465; LA64: # %bb.0:466; LA64-NEXT: bstrpick.d $a0, $a0, 15, 4467; LA64-NEXT: slli.d $a0, $a0, 4468; LA64-NEXT: bstrpick.d $a1, $a1, 15, 4469; LA64-NEXT: slli.d $a1, $a1, 4470; LA64-NEXT: sub.d $a0, $a0, $a1471; LA64-NEXT: ret472 %c = and i64 %a, 65520473 %d = and i64 %b, 65520474 %e = sub i64 %c, %d475 ret i64 %e476}477 478;; This case is not optimized to `bstrpick + slli`,479;; since the immediate 1044480 can be composed via480;; a single `lu12i.w $rx, 255`.481define i64 @and_i64_0xff000(i64 %a) {482; LA32R-LABEL: and_i64_0xff000:483; LA32R: # %bb.0:484; LA32R-NEXT: lu12i.w $a1, 255485; LA32R-NEXT: and $a0, $a0, $a1486; LA32R-NEXT: move $a1, $zero487; LA32R-NEXT: ret488;489; LA32S-LABEL: and_i64_0xff000:490; LA32S: # %bb.0:491; LA32S-NEXT: lu12i.w $a1, 255492; LA32S-NEXT: and $a0, $a0, $a1493; LA32S-NEXT: move $a1, $zero494; LA32S-NEXT: ret495;496; LA64-LABEL: and_i64_0xff000:497; LA64: # %bb.0:498; LA64-NEXT: lu12i.w $a1, 255499; LA64-NEXT: and $a0, $a0, $a1500; LA64-NEXT: ret501 %b = and i64 %a, 1044480502 ret i64 %b503}504 505define i64 @and_i64_minus_2048(i64 %a) {506; LA32R-LABEL: and_i64_minus_2048:507; LA32R: # %bb.0:508; LA32R-NEXT: addi.w $a2, $zero, -2048509; LA32R-NEXT: and $a0, $a0, $a2510; LA32R-NEXT: ret511;512; LA32S-LABEL: and_i64_minus_2048:513; LA32S: # %bb.0:514; LA32S-NEXT: bstrins.w $a0, $zero, 10, 0515; LA32S-NEXT: ret516;517; LA64-LABEL: and_i64_minus_2048:518; LA64: # %bb.0:519; LA64-NEXT: bstrins.d $a0, $zero, 10, 0520; LA64-NEXT: ret521 %b = and i64 %a, -2048522 ret i64 %b523}524 525;; This case is not optimized to `bstrpick + slli`,526;; since the immediate 0xfff0 has more than 2 uses.527define i64 @and_i64_0xfff0_multiple_times(i64 %a, i64 %b, i64 %c) {528; LA32R-LABEL: and_i64_0xfff0_multiple_times:529; LA32R: # %bb.0:530; LA32R-NEXT: lu12i.w $a1, 15531; LA32R-NEXT: ori $a1, $a1, 4080532; LA32R-NEXT: and $a0, $a0, $a1533; LA32R-NEXT: and $a2, $a2, $a1534; LA32R-NEXT: and $a3, $a4, $a1535; LA32R-NEXT: sltu $a1, $a0, $a2536; LA32R-NEXT: sub.w $a1, $zero, $a1537; LA32R-NEXT: sub.w $a0, $a0, $a2538; LA32R-NEXT: mul.w $a2, $a2, $a3539; LA32R-NEXT: xor $a0, $a0, $a2540; LA32R-NEXT: ret541;542; LA32S-LABEL: and_i64_0xfff0_multiple_times:543; LA32S: # %bb.0:544; LA32S-NEXT: lu12i.w $a1, 15545; LA32S-NEXT: ori $a1, $a1, 4080546; LA32S-NEXT: and $a0, $a0, $a1547; LA32S-NEXT: and $a2, $a2, $a1548; LA32S-NEXT: and $a3, $a4, $a1549; LA32S-NEXT: sltu $a1, $a0, $a2550; LA32S-NEXT: sub.w $a1, $zero, $a1551; LA32S-NEXT: sub.w $a0, $a0, $a2552; LA32S-NEXT: mul.w $a2, $a2, $a3553; LA32S-NEXT: xor $a0, $a0, $a2554; LA32S-NEXT: ret555;556; LA64-LABEL: and_i64_0xfff0_multiple_times:557; LA64: # %bb.0:558; LA64-NEXT: lu12i.w $a3, 15559; LA64-NEXT: ori $a3, $a3, 4080560; LA64-NEXT: and $a0, $a0, $a3561; LA64-NEXT: and $a1, $a1, $a3562; LA64-NEXT: and $a2, $a2, $a3563; LA64-NEXT: sub.d $a0, $a0, $a1564; LA64-NEXT: mul.d $a1, $a1, $a2565; LA64-NEXT: xor $a0, $a0, $a1566; LA64-NEXT: ret567 %d = and i64 %a, 65520568 %e = and i64 %b, 65520569 %f = and i64 %c, 65520570 %g = sub i64 %d, %e571 %h = mul i64 %e, %f572 %i = xor i64 %g, %h573 ret i64 %i574}575 576define i64 @and_i64_0xffffffffff00ffff(i64 %a) {577; LA32R-LABEL: and_i64_0xffffffffff00ffff:578; LA32R: # %bb.0:579; LA32R-NEXT: lu12i.w $a2, -4081580; LA32R-NEXT: ori $a2, $a2, 4095581; LA32R-NEXT: and $a0, $a0, $a2582; LA32R-NEXT: ret583;584; LA32S-LABEL: and_i64_0xffffffffff00ffff:585; LA32S: # %bb.0:586; LA32S-NEXT: bstrins.w $a0, $zero, 23, 16587; LA32S-NEXT: ret588;589; LA64-LABEL: and_i64_0xffffffffff00ffff:590; LA64: # %bb.0:591; LA64-NEXT: bstrins.d $a0, $zero, 23, 16592; LA64-NEXT: ret593 %b = and i64 %a, 18446744073692839935594 ret i64 %b595}596 597define i32 @and_add_lsr(i32 %x, i32 %y) {598; LA32R-LABEL: and_add_lsr:599; LA32R: # %bb.0:600; LA32R-NEXT: addi.w $a0, $a0, -1601; LA32R-NEXT: srli.w $a1, $a1, 20602; LA32R-NEXT: and $a0, $a1, $a0603; LA32R-NEXT: ret604;605; LA32S-LABEL: and_add_lsr:606; LA32S: # %bb.0:607; LA32S-NEXT: addi.w $a0, $a0, -1608; LA32S-NEXT: srli.w $a1, $a1, 20609; LA32S-NEXT: and $a0, $a1, $a0610; LA32S-NEXT: ret611;612; LA64-LABEL: and_add_lsr:613; LA64: # %bb.0:614; LA64-NEXT: addi.w $a0, $a0, -1615; LA64-NEXT: bstrpick.d $a1, $a1, 31, 20616; LA64-NEXT: and $a0, $a1, $a0617; LA64-NEXT: ret618 %1 = add i32 %x, 4095619 %2 = lshr i32 %y, 20620 %r = and i32 %2, %1621 ret i32 %r622}623