brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.2 KiB · 05e7b2a Raw
296 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -o - %s -mtriple=x86_64-- | FileCheck %s --check-prefixes=CHECK,NOBMI3; RUN: llc -o - %s -mtriple=x86_64-- -mattr=+bmi | FileCheck %s --check-prefixes=CHECK,BMI4;5; test that masked-merge code is generated as "xor;and;xor" sequence or6; "andn ; and; or" if and-not is available.7 8define i32 @masked_merge0(i32 %a0, i32 %a1, i32 %a2) {9; NOBMI-LABEL: masked_merge0:10; NOBMI:       # %bb.0:11; NOBMI-NEXT:    movl %esi, %eax12; NOBMI-NEXT:    xorl %edx, %eax13; NOBMI-NEXT:    andl %edi, %eax14; NOBMI-NEXT:    xorl %edx, %eax15; NOBMI-NEXT:    retq16;17; BMI-LABEL: masked_merge0:18; BMI:       # %bb.0:19; BMI-NEXT:    andl %edi, %esi20; BMI-NEXT:    andnl %edx, %edi, %eax21; BMI-NEXT:    orl %esi, %eax22; BMI-NEXT:    retq23  %and0 = and i32 %a0, %a124  %not = xor i32 %a0, -125  %and1 = and i32 %not, %a226  %or = or i32 %and0, %and127  ret i32 %or28}29 30define i16 @masked_merge1(i16 %a0, i16 %a1, i16 %a2) {31; NOBMI-LABEL: masked_merge1:32; NOBMI:       # %bb.0:33; NOBMI-NEXT:    movl %esi, %eax34; NOBMI-NEXT:    xorl %edx, %eax35; NOBMI-NEXT:    andl %edi, %eax36; NOBMI-NEXT:    xorl %edx, %eax37; NOBMI-NEXT:    # kill: def $ax killed $ax killed $eax38; NOBMI-NEXT:    retq39;40; BMI-LABEL: masked_merge1:41; BMI:       # %bb.0:42; BMI-NEXT:    andnl %edx, %edi, %eax43; BMI-NEXT:    andl %edi, %esi44; BMI-NEXT:    orl %esi, %eax45; BMI-NEXT:    # kill: def $ax killed $ax killed $eax46; BMI-NEXT:    retq47  %and0 = and i16 %a0, %a148  %not = xor i16 %a0, -149  %and1 = and i16 %a2, %not50  %or = or i16 %and0, %and151  ret i16 %or52}53 54define i8 @masked_merge2(i8 %a0, i8 %a1, i8 %a2) {55; CHECK-LABEL: masked_merge2:56; CHECK:       # %bb.0:57; CHECK-NEXT:    movl %esi, %eax58; CHECK-NEXT:    # kill: def $al killed $al killed $eax59; CHECK-NEXT:    retq60  %not = xor i8 %a0, -161  %and0 = and i8 %not, %a162  %and1 = and i8 %a1, %a063  %or = or i8 %and0, %and164  ret i8 %or65}66 67define i64 @masked_merge3(i64 %a0, i64 %a1, i64 %a2) {68; NOBMI-LABEL: masked_merge3:69; NOBMI:       # %bb.0:70; NOBMI-NEXT:    movq %rsi, %rax71; NOBMI-NEXT:    notq %rdx72; NOBMI-NEXT:    xorq %rdx, %rax73; NOBMI-NEXT:    notq %rax74; NOBMI-NEXT:    andq %rdi, %rax75; NOBMI-NEXT:    xorq %rdx, %rax76; NOBMI-NEXT:    retq77;78; BMI-LABEL: masked_merge3:79; BMI:       # %bb.0:80; BMI-NEXT:    notq %rdx81; BMI-NEXT:    andnq %rdx, %rdi, %rcx82; BMI-NEXT:    andnq %rdi, %rsi, %rax83; BMI-NEXT:    orq %rcx, %rax84; BMI-NEXT:    retq85  %v0 = xor i64 %a1, -186  %v1 = xor i64 %a2, -187  %not = xor i64 %a0, -188  %and0 = and i64 %not, %v189  %and1 = and i64 %v0, %a090  %or = or i64 %and0, %and191  ret i64 %or92}93 94; not a masked merge: there is no `not` operation.95define i32 @not_a_masked_merge0(i32 %a0, i32 %a1, i32 %a2) {96; CHECK-LABEL: not_a_masked_merge0:97; CHECK:       # %bb.0:98; CHECK-NEXT:    movl %edi, %eax99; CHECK-NEXT:    andl %edi, %esi100; CHECK-NEXT:    negl %eax101; CHECK-NEXT:    andl %edx, %eax102; CHECK-NEXT:    orl %esi, %eax103; CHECK-NEXT:    retq104  %and0 = and i32 %a0, %a1105  %not_a_not = sub i32 0, %a0106  %and1 = and i32 %not_a_not, %a2107  %or = or i32 %and0, %and1108  ret i32 %or109}110 111; not a masked merge: `not` operand does not match another `and`-operand.112define i32 @not_a_masked_merge1(i32 %a0, i32 %a1, i32 %a2, i32 %a3) {113; NOBMI-LABEL: not_a_masked_merge1:114; NOBMI:       # %bb.0:115; NOBMI-NEXT:    movl %ecx, %eax116; NOBMI-NEXT:    andl %esi, %edi117; NOBMI-NEXT:    notl %eax118; NOBMI-NEXT:    andl %edx, %eax119; NOBMI-NEXT:    orl %edi, %eax120; NOBMI-NEXT:    retq121;122; BMI-LABEL: not_a_masked_merge1:123; BMI:       # %bb.0:124; BMI-NEXT:    andl %esi, %edi125; BMI-NEXT:    andnl %edx, %ecx, %eax126; BMI-NEXT:    orl %edi, %eax127; BMI-NEXT:    retq128  %and0 = and i32 %a0, %a1129  %not = xor i32 %a3, -1130  %and1 = and i32 %not, %a2131  %or = or i32 %and0, %and1132  ret i32 %or133}134 135; not a masked merge: one of the operands of `or` is not an `and`.136define i32 @not_a_masked_merge2(i32 %a0, i32 %a1, i32 %a2) {137; NOBMI-LABEL: not_a_masked_merge2:138; NOBMI:       # %bb.0:139; NOBMI-NEXT:    movl %edi, %eax140; NOBMI-NEXT:    orl %edi, %esi141; NOBMI-NEXT:    notl %eax142; NOBMI-NEXT:    andl %edx, %eax143; NOBMI-NEXT:    orl %esi, %eax144; NOBMI-NEXT:    retq145;146; BMI-LABEL: not_a_masked_merge2:147; BMI:       # %bb.0:148; BMI-NEXT:    orl %edi, %esi149; BMI-NEXT:    andnl %edx, %edi, %eax150; BMI-NEXT:    orl %esi, %eax151; BMI-NEXT:    retq152  %not_an_and0 = or i32 %a0, %a1153  %not = xor i32 %a0, -1154  %and1 = and i32 %not, %a2155  %or = or i32 %not_an_and0, %and1156  ret i32 %or157}158 159; not a masked merge: one of the operands of `or` is not an `and`.160define i32 @not_a_masked_merge3(i32 %a0, i32 %a1, i32 %a2) {161; CHECK-LABEL: not_a_masked_merge3:162; CHECK:       # %bb.0:163; CHECK-NEXT:    movl %edx, %eax164; CHECK-NEXT:    andl %edi, %esi165; CHECK-NEXT:    xorl %edi, %eax166; CHECK-NEXT:    notl %eax167; CHECK-NEXT:    orl %esi, %eax168; CHECK-NEXT:    retq169  %and0 = and i32 %a0, %a1170  %not = xor i32 %a0, -1171  %not_an_and1 = xor i32 %not, %a2172  %or = or i32 %and0, %not_an_and1173  ret i32 %or174}175 176; not a masked merge: `not` operand must not be on same `and`.177define i32 @not_a_masked_merge4(i32 %a0, i32 %a1, i32 %a2) {178; CHECK-LABEL: not_a_masked_merge4:179; CHECK:       # %bb.0:180; CHECK-NEXT:    movl %edi, %eax181; CHECK-NEXT:    andl %esi, %eax182; CHECK-NEXT:    retq183  %and0 = and i32 %a0, %a1184  %not = xor i32 %a2, -1185  %and1 = and i32 %not, %a2186  %or = or i32 %and0, %and1187  ret i32 %or188}189 190; should not transform when operands have multiple users.191define i32 @masked_merge_no_transform0(i32 %a0, i32 %a1, i32 %a2, ptr %p1) {192; NOBMI-LABEL: masked_merge_no_transform0:193; NOBMI:       # %bb.0:194; NOBMI-NEXT:    movl %edi, %eax195; NOBMI-NEXT:    andl %edi, %esi196; NOBMI-NEXT:    notl %eax197; NOBMI-NEXT:    andl %edx, %eax198; NOBMI-NEXT:    orl %esi, %eax199; NOBMI-NEXT:    movl %esi, (%rcx)200; NOBMI-NEXT:    retq201;202; BMI-LABEL: masked_merge_no_transform0:203; BMI:       # %bb.0:204; BMI-NEXT:    andl %edi, %esi205; BMI-NEXT:    andnl %edx, %edi, %eax206; BMI-NEXT:    orl %esi, %eax207; BMI-NEXT:    movl %esi, (%rcx)208; BMI-NEXT:    retq209  %and0 = and i32 %a0, %a1210  %not = xor i32 %a0, -1211  %and1 = and i32 %not, %a2212  %or = or i32 %and0, %and1213  store i32 %and0, ptr %p1214  ret i32 %or215}216 217; should not transform when operands have multiple users.218define i32 @masked_merge_no_transform1(i32 %a0, i32 %a1, i32 %a2, ptr %p1) {219; NOBMI-LABEL: masked_merge_no_transform1:220; NOBMI:       # %bb.0:221; NOBMI-NEXT:    movl %edx, %eax222; NOBMI-NEXT:    andl %edi, %esi223; NOBMI-NEXT:    notl %edi224; NOBMI-NEXT:    andl %edi, %eax225; NOBMI-NEXT:    orl %esi, %eax226; NOBMI-NEXT:    movl %edi, (%rcx)227; NOBMI-NEXT:    retq228;229; BMI-LABEL: masked_merge_no_transform1:230; BMI:       # %bb.0:231; BMI-NEXT:    andl %edi, %esi232; BMI-NEXT:    andnl %edx, %edi, %eax233; BMI-NEXT:    notl %edi234; BMI-NEXT:    orl %esi, %eax235; BMI-NEXT:    movl %edi, (%rcx)236; BMI-NEXT:    retq237  %and0 = and i32 %a0, %a1238  %not = xor i32 %a0, -1239  %and1 = and i32 %not, %a2240  %or = or i32 %and0, %and1241  store i32 %not, ptr %p1242  ret i32 %or243}244 245; should not transform when operands have multiple users.246define i32 @masked_merge_no_transform2(i32 %a0, i32 %a1, i32 %a2, ptr %p1) {247; NOBMI-LABEL: masked_merge_no_transform2:248; NOBMI:       # %bb.0:249; NOBMI-NEXT:    movl %esi, %eax250; NOBMI-NEXT:    andl %edi, %eax251; NOBMI-NEXT:    notl %edi252; NOBMI-NEXT:    andl %edx, %edi253; NOBMI-NEXT:    orl %edi, %eax254; NOBMI-NEXT:    movl %edi, (%rcx)255; NOBMI-NEXT:    retq256;257; BMI-LABEL: masked_merge_no_transform2:258; BMI:       # %bb.0:259; BMI-NEXT:    movl %esi, %eax260; BMI-NEXT:    andl %edi, %eax261; BMI-NEXT:    andnl %edx, %edi, %edx262; BMI-NEXT:    orl %edx, %eax263; BMI-NEXT:    movl %edx, (%rcx)264; BMI-NEXT:    retq265  %and0 = and i32 %a0, %a1266  %not = xor i32 %a0, -1267  %and1 = and i32 %not, %a2268  %or = or i32 %and0, %and1269  store i32 %and1, ptr %p1270  ret i32 %or271}272 273define i32 @pr137641_crash({ i8, i32 } %0) {274; NOBMI-LABEL: pr137641_crash:275; NOBMI:       # %bb.0:276; NOBMI-NEXT:    movl %esi, %eax277; NOBMI-NEXT:    andl $201, %eax278; NOBMI-NEXT:    xorl $1, %eax279; NOBMI-NEXT:    retq280;281; BMI-LABEL: pr137641_crash:282; BMI:       # %bb.0:283; BMI-NEXT:    movl %esi, %eax284; BMI-NEXT:    notl %eax285; BMI-NEXT:    andl $1, %eax286; BMI-NEXT:    andl $200, %esi287; BMI-NEXT:    orl %esi, %eax288; BMI-NEXT:    retq289  %asmresult1.i = extractvalue { i8, i32 } %0, 1290  %not = xor i32 %asmresult1.i, 1291  %and = and i32 1, %not292  %and1 = and i32 %asmresult1.i, 200293  %2 = or i32 %and, %and1294  ret i32 %2295}296