303 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -mtriple=riscv32 < %s \3; RUN: | FileCheck %s --check-prefixes=CHECK,CHECK-I,RV32,RV32I4; RUN: llc -mtriple=riscv64 < %s \5; RUN: | FileCheck %s --check-prefixes=CHECK,CHECK-I,RV64,RV64I6; RUN: llc -mtriple=riscv32 -mattr=+zbb < %s \7; RUN: | FileCheck %s --check-prefixes=CHECK,CHECK-ZBB,RV32,RV32ZBB8; RUN: llc -mtriple=riscv64 -mattr=+zbb < %s \9; RUN: | FileCheck %s --check-prefixes=CHECK,CHECK-ZBB,RV64,RV64ZBB10;11; test that masked-merge code is generated as "xor;and;xor" sequence or12; "andn ; and; or" if and-not is available.13 14define i32 @masked_merge0(i32 %a0, i32 %a1, i32 %a2) {15; CHECK-I-LABEL: masked_merge0:16; CHECK-I: # %bb.0:17; CHECK-I-NEXT: xor a1, a1, a218; CHECK-I-NEXT: and a0, a1, a019; CHECK-I-NEXT: xor a0, a0, a220; CHECK-I-NEXT: ret21;22; CHECK-ZBB-LABEL: masked_merge0:23; CHECK-ZBB: # %bb.0:24; CHECK-ZBB-NEXT: and a1, a0, a125; CHECK-ZBB-NEXT: andn a0, a2, a026; CHECK-ZBB-NEXT: or a0, a1, a027; CHECK-ZBB-NEXT: ret28 %and0 = and i32 %a0, %a129 %not = xor i32 %a0, -130 %and1 = and i32 %not, %a231 %or = or i32 %and0, %and132 ret i32 %or33}34 35define i16 @masked_merge1(i16 %a0, i16 %a1, i16 %a2) {36; CHECK-I-LABEL: masked_merge1:37; CHECK-I: # %bb.0:38; CHECK-I-NEXT: xor a1, a1, a239; CHECK-I-NEXT: and a0, a1, a040; CHECK-I-NEXT: xor a0, a0, a241; CHECK-I-NEXT: ret42;43; CHECK-ZBB-LABEL: masked_merge1:44; CHECK-ZBB: # %bb.0:45; CHECK-ZBB-NEXT: and a1, a0, a146; CHECK-ZBB-NEXT: andn a0, a2, a047; CHECK-ZBB-NEXT: or a0, a1, a048; CHECK-ZBB-NEXT: ret49 %and0 = and i16 %a0, %a150 %not = xor i16 %a0, -151 %and1 = and i16 %a2, %not52 %or = or i16 %and0, %and153 ret i16 %or54}55 56define i8 @masked_merge2(i8 %a0, i8 %a1, i8 %a2) {57; CHECK-I-LABEL: masked_merge2:58; CHECK-I: # %bb.0:59; CHECK-I-NEXT: mv a0, a160; CHECK-I-NEXT: ret61;62; CHECK-ZBB-LABEL: masked_merge2:63; CHECK-ZBB: # %bb.0:64; CHECK-ZBB-NEXT: andn a2, a1, a065; CHECK-ZBB-NEXT: and a0, a1, a066; CHECK-ZBB-NEXT: or a0, a2, a067; CHECK-ZBB-NEXT: ret68 %not = xor i8 %a0, -169 %and0 = and i8 %not, %a170 %and1 = and i8 %a1, %a071 %or = or i8 %and0, %and172 ret i8 %or73}74 75define i64 @masked_merge3(i64 %a0, i64 %a1, i64 %a2) {76; RV32I-LABEL: masked_merge3:77; RV32I: # %bb.0:78; RV32I-NEXT: not a5, a579; RV32I-NEXT: not a4, a480; RV32I-NEXT: xor a3, a3, a581; RV32I-NEXT: xor a2, a2, a482; RV32I-NEXT: not a2, a283; RV32I-NEXT: not a3, a384; RV32I-NEXT: and a0, a2, a085; RV32I-NEXT: and a1, a3, a186; RV32I-NEXT: xor a0, a0, a487; RV32I-NEXT: xor a1, a1, a588; RV32I-NEXT: ret89;90; RV64I-LABEL: masked_merge3:91; RV64I: # %bb.0:92; RV64I-NEXT: not a2, a293; RV64I-NEXT: xor a1, a1, a294; RV64I-NEXT: not a1, a195; RV64I-NEXT: and a0, a1, a096; RV64I-NEXT: xor a0, a0, a297; RV64I-NEXT: ret98;99; RV32ZBB-LABEL: masked_merge3:100; RV32ZBB: # %bb.0:101; RV32ZBB-NEXT: not a6, a0102; RV32ZBB-NEXT: not a7, a1103; RV32ZBB-NEXT: andn a1, a1, a3104; RV32ZBB-NEXT: andn a0, a0, a2105; RV32ZBB-NEXT: andn a2, a7, a5106; RV32ZBB-NEXT: andn a3, a6, a4107; RV32ZBB-NEXT: or a0, a3, a0108; RV32ZBB-NEXT: or a1, a2, a1109; RV32ZBB-NEXT: ret110;111; RV64ZBB-LABEL: masked_merge3:112; RV64ZBB: # %bb.0:113; RV64ZBB-NEXT: not a3, a0114; RV64ZBB-NEXT: andn a2, a3, a2115; RV64ZBB-NEXT: andn a0, a0, a1116; RV64ZBB-NEXT: or a0, a2, a0117; RV64ZBB-NEXT: ret118 %v0 = xor i64 %a1, -1119 %v1 = xor i64 %a2, -1120 %not = xor i64 %a0, -1121 %and0 = and i64 %not, %v1122 %and1 = and i64 %v0, %a0123 %or = or i64 %and0, %and1124 ret i64 %or125}126 127define i32 @not_a_masked_merge0(i32 %a0, i32 %a1, i32 %a2) {128; RV32-LABEL: not_a_masked_merge0:129; RV32: # %bb.0:130; RV32-NEXT: and a1, a0, a1131; RV32-NEXT: neg a0, a0132; RV32-NEXT: and a0, a0, a2133; RV32-NEXT: or a0, a1, a0134; RV32-NEXT: ret135;136; RV64-LABEL: not_a_masked_merge0:137; RV64: # %bb.0:138; RV64-NEXT: and a1, a0, a1139; RV64-NEXT: negw a0, a0140; RV64-NEXT: and a0, a0, a2141; RV64-NEXT: or a0, a1, a0142; RV64-NEXT: ret143 %and0 = and i32 %a0, %a1144 %not_a_not = sub i32 0, %a0145 %and1 = and i32 %not_a_not, %a2146 %or = or i32 %and0, %and1147 ret i32 %or148}149 150define i32 @not_a_masked_merge1(i32 %a0, i32 %a1, i32 %a2, i32 %a3) {151; CHECK-I-LABEL: not_a_masked_merge1:152; CHECK-I: # %bb.0:153; CHECK-I-NEXT: and a0, a0, a1154; CHECK-I-NEXT: not a1, a3155; CHECK-I-NEXT: and a1, a1, a2156; CHECK-I-NEXT: or a0, a0, a1157; CHECK-I-NEXT: ret158;159; CHECK-ZBB-LABEL: not_a_masked_merge1:160; CHECK-ZBB: # %bb.0:161; CHECK-ZBB-NEXT: and a0, a0, a1162; CHECK-ZBB-NEXT: andn a1, a2, a3163; CHECK-ZBB-NEXT: or a0, a0, a1164; CHECK-ZBB-NEXT: ret165 %and0 = and i32 %a0, %a1166 %not = xor i32 %a3, -1167 %and1 = and i32 %not, %a2168 %or = or i32 %and0, %and1169 ret i32 %or170}171 172define i32 @not_a_masked_merge2(i32 %a0, i32 %a1, i32 %a2) {173; CHECK-I-LABEL: not_a_masked_merge2:174; CHECK-I: # %bb.0:175; CHECK-I-NEXT: or a1, a0, a1176; CHECK-I-NEXT: not a0, a0177; CHECK-I-NEXT: and a0, a0, a2178; CHECK-I-NEXT: or a0, a1, a0179; CHECK-I-NEXT: ret180;181; CHECK-ZBB-LABEL: not_a_masked_merge2:182; CHECK-ZBB: # %bb.0:183; CHECK-ZBB-NEXT: or a1, a0, a1184; CHECK-ZBB-NEXT: andn a0, a2, a0185; CHECK-ZBB-NEXT: or a0, a1, a0186; CHECK-ZBB-NEXT: ret187 %not_an_and0 = or i32 %a0, %a1188 %not = xor i32 %a0, -1189 %and1 = and i32 %not, %a2190 %or = or i32 %not_an_and0, %and1191 ret i32 %or192}193 194define i32 @not_a_masked_merge3(i32 %a0, i32 %a1, i32 %a2) {195; CHECK-I-LABEL: not_a_masked_merge3:196; CHECK-I: # %bb.0:197; CHECK-I-NEXT: and a1, a0, a1198; CHECK-I-NEXT: xor a0, a0, a2199; CHECK-I-NEXT: not a0, a0200; CHECK-I-NEXT: or a0, a1, a0201; CHECK-I-NEXT: ret202;203; CHECK-ZBB-LABEL: not_a_masked_merge3:204; CHECK-ZBB: # %bb.0:205; CHECK-ZBB-NEXT: and a1, a0, a1206; CHECK-ZBB-NEXT: xor a0, a0, a2207; CHECK-ZBB-NEXT: orn a0, a1, a0208; CHECK-ZBB-NEXT: ret209 %and0 = and i32 %a0, %a1210 %not = xor i32 %a0, -1211 %not_an_and1 = xor i32 %not, %a2212 %or = or i32 %and0, %not_an_and1213 ret i32 %or214}215 216define i32 @not_a_masked_merge4(i32 %a0, i32 %a1, i32 %a2) {217; CHECK-LABEL: not_a_masked_merge4:218; CHECK: # %bb.0:219; CHECK-NEXT: and a0, a0, a1220; CHECK-NEXT: ret221 %and0 = and i32 %a0, %a1222 %not = xor i32 %a2, -1223 %and1 = and i32 %not, %a2224 %or = or i32 %and0, %and1225 ret i32 %or226}227 228define i32 @masked_merge_no_transform0(i32 %a0, i32 %a1, i32 %a2, ptr %p1) {229; CHECK-I-LABEL: masked_merge_no_transform0:230; CHECK-I: # %bb.0:231; CHECK-I-NEXT: and a1, a0, a1232; CHECK-I-NEXT: not a0, a0233; CHECK-I-NEXT: and a0, a0, a2234; CHECK-I-NEXT: or a0, a1, a0235; CHECK-I-NEXT: sw a1, 0(a3)236; CHECK-I-NEXT: ret237;238; CHECK-ZBB-LABEL: masked_merge_no_transform0:239; CHECK-ZBB: # %bb.0:240; CHECK-ZBB-NEXT: and a1, a0, a1241; CHECK-ZBB-NEXT: andn a0, a2, a0242; CHECK-ZBB-NEXT: or a0, a1, a0243; CHECK-ZBB-NEXT: sw a1, 0(a3)244; CHECK-ZBB-NEXT: ret245 %and0 = and i32 %a0, %a1246 %not = xor i32 %a0, -1247 %and1 = and i32 %not, %a2248 %or = or i32 %and0, %and1249 store i32 %and0, ptr %p1250 ret i32 %or251}252 253define i32 @masked_merge_no_transform1(i32 %a0, i32 %a1, i32 %a2, ptr %p1) {254; CHECK-I-LABEL: masked_merge_no_transform1:255; CHECK-I: # %bb.0:256; CHECK-I-NEXT: and a1, a0, a1257; CHECK-I-NEXT: not a4, a0258; CHECK-I-NEXT: and a0, a4, a2259; CHECK-I-NEXT: or a0, a1, a0260; CHECK-I-NEXT: sw a4, 0(a3)261; CHECK-I-NEXT: ret262;263; CHECK-ZBB-LABEL: masked_merge_no_transform1:264; CHECK-ZBB: # %bb.0:265; CHECK-ZBB-NEXT: and a1, a0, a1266; CHECK-ZBB-NEXT: not a4, a0267; CHECK-ZBB-NEXT: andn a0, a2, a0268; CHECK-ZBB-NEXT: or a0, a1, a0269; CHECK-ZBB-NEXT: sw a4, 0(a3)270; CHECK-ZBB-NEXT: ret271 %and0 = and i32 %a0, %a1272 %not = xor i32 %a0, -1273 %and1 = and i32 %not, %a2274 %or = or i32 %and0, %and1275 store i32 %not, ptr %p1276 ret i32 %or277}278 279define i32 @masked_merge_no_transform2(i32 %a0, i32 %a1, i32 %a2, ptr %p1) {280; CHECK-I-LABEL: masked_merge_no_transform2:281; CHECK-I: # %bb.0:282; CHECK-I-NEXT: and a1, a0, a1283; CHECK-I-NEXT: not a0, a0284; CHECK-I-NEXT: and a2, a0, a2285; CHECK-I-NEXT: or a0, a1, a2286; CHECK-I-NEXT: sw a2, 0(a3)287; CHECK-I-NEXT: ret288;289; CHECK-ZBB-LABEL: masked_merge_no_transform2:290; CHECK-ZBB: # %bb.0:291; CHECK-ZBB-NEXT: and a1, a0, a1292; CHECK-ZBB-NEXT: andn a2, a2, a0293; CHECK-ZBB-NEXT: or a0, a1, a2294; CHECK-ZBB-NEXT: sw a2, 0(a3)295; CHECK-ZBB-NEXT: ret296 %and0 = and i32 %a0, %a1297 %not = xor i32 %a0, -1298 %and1 = and i32 %not, %a2299 %or = or i32 %and0, %and1300 store i32 %and1, ptr %p1301 ret i32 %or302}303