@@ -319,3 +319,166 @@ define i1 @xor_icmp_to_icmp_add_multiuse2(i32 %a) {
319319 %cmp3 = xor i1 %cmp , %cmp1
320320 ret i1 %cmp3
321321}
322+
323+ define i1 @test_xor_of_bittest_ne_ne (i8 %x , i8 %y ) {
324+ ; CHECK-LABEL: @test_xor_of_bittest_ne_ne(
325+ ; CHECK-NEXT: [[MASK1:%.*]] = and i8 [[X:%.*]], 2
326+ ; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i8 [[MASK1]], 0
327+ ; CHECK-NEXT: [[MASK2:%.*]] = and i8 [[Y:%.*]], 2
328+ ; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i8 [[MASK2]], 0
329+ ; CHECK-NEXT: [[XOR:%.*]] = xor i1 [[CMP1]], [[CMP2]]
330+ ; CHECK-NEXT: ret i1 [[XOR]]
331+ ;
332+ %mask1 = and i8 %x , 2
333+ %cmp1 = icmp ne i8 %mask1 , 0
334+ %mask2 = and i8 %y , 2
335+ %cmp2 = icmp ne i8 %mask2 , 0
336+ %xor = xor i1 %cmp1 , %cmp2
337+ ret i1 %xor
338+ }
339+
340+ define i1 @test_xor_of_bittest_eq_eq (i8 %x , i8 %y ) {
341+ ; CHECK-LABEL: @test_xor_of_bittest_eq_eq(
342+ ; CHECK-NEXT: [[MASK1:%.*]] = and i8 [[X:%.*]], 2
343+ ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[MASK1]], 0
344+ ; CHECK-NEXT: [[MASK2:%.*]] = and i8 [[Y:%.*]], 2
345+ ; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i8 [[MASK2]], 0
346+ ; CHECK-NEXT: [[XOR:%.*]] = xor i1 [[CMP1]], [[CMP2]]
347+ ; CHECK-NEXT: ret i1 [[XOR]]
348+ ;
349+ %mask1 = and i8 %x , 2
350+ %cmp1 = icmp eq i8 %mask1 , 0
351+ %mask2 = and i8 %y , 2
352+ %cmp2 = icmp eq i8 %mask2 , 0
353+ %xor = xor i1 %cmp1 , %cmp2
354+ ret i1 %xor
355+ }
356+
357+ define i1 @test_xor_of_bittest_ne_eq (i8 %x , i8 %y ) {
358+ ; CHECK-LABEL: @test_xor_of_bittest_ne_eq(
359+ ; CHECK-NEXT: [[MASK1:%.*]] = and i8 [[X:%.*]], 2
360+ ; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i8 [[MASK1]], 0
361+ ; CHECK-NEXT: [[MASK2:%.*]] = and i8 [[Y:%.*]], 2
362+ ; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i8 [[MASK2]], 0
363+ ; CHECK-NEXT: [[XOR:%.*]] = xor i1 [[CMP1]], [[CMP2]]
364+ ; CHECK-NEXT: ret i1 [[XOR]]
365+ ;
366+ %mask1 = and i8 %x , 2
367+ %cmp1 = icmp ne i8 %mask1 , 0
368+ %mask2 = and i8 %y , 2
369+ %cmp2 = icmp eq i8 %mask2 , 0
370+ %xor = xor i1 %cmp1 , %cmp2
371+ ret i1 %xor
372+ }
373+
374+ define i1 @test_xor_of_bittest_eq_ne (i8 %x , i8 %y ) {
375+ ; CHECK-LABEL: @test_xor_of_bittest_eq_ne(
376+ ; CHECK-NEXT: [[MASK1:%.*]] = and i8 [[X:%.*]], 2
377+ ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[MASK1]], 0
378+ ; CHECK-NEXT: [[MASK2:%.*]] = and i8 [[Y:%.*]], 2
379+ ; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i8 [[MASK2]], 0
380+ ; CHECK-NEXT: [[XOR:%.*]] = xor i1 [[CMP1]], [[CMP2]]
381+ ; CHECK-NEXT: ret i1 [[XOR]]
382+ ;
383+ %mask1 = and i8 %x , 2
384+ %cmp1 = icmp eq i8 %mask1 , 0
385+ %mask2 = and i8 %y , 2
386+ %cmp2 = icmp ne i8 %mask2 , 0
387+ %xor = xor i1 %cmp1 , %cmp2
388+ ret i1 %xor
389+ }
390+
391+ define i1 @test_xor_of_bittest_ne_ne_multiuse1 (i8 %x , i8 %y ) {
392+ ; CHECK-LABEL: @test_xor_of_bittest_ne_ne_multiuse1(
393+ ; CHECK-NEXT: [[MASK1:%.*]] = and i8 [[X:%.*]], 2
394+ ; CHECK-NEXT: call void @usei8(i8 [[MASK1]])
395+ ; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i8 [[MASK1]], 0
396+ ; CHECK-NEXT: [[MASK2:%.*]] = and i8 [[Y:%.*]], 2
397+ ; CHECK-NEXT: call void @usei8(i8 [[MASK2]])
398+ ; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i8 [[MASK2]], 0
399+ ; CHECK-NEXT: [[XOR:%.*]] = xor i1 [[CMP1]], [[CMP2]]
400+ ; CHECK-NEXT: ret i1 [[XOR]]
401+ ;
402+ %mask1 = and i8 %x , 2
403+ call void @usei8 (i8 %mask1 )
404+ %cmp1 = icmp ne i8 %mask1 , 0
405+ %mask2 = and i8 %y , 2
406+ call void @usei8 (i8 %mask2 )
407+ %cmp2 = icmp ne i8 %mask2 , 0
408+ %xor = xor i1 %cmp1 , %cmp2
409+ ret i1 %xor
410+ }
411+
412+ ; Negative tests
413+
414+ define i1 @test_xor_of_bittest_ne_ne_type_mismatch (i8 %x , i16 %y ) {
415+ ; CHECK-LABEL: @test_xor_of_bittest_ne_ne_type_mismatch(
416+ ; CHECK-NEXT: [[MASK1:%.*]] = and i8 [[X:%.*]], 2
417+ ; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i8 [[MASK1]], 0
418+ ; CHECK-NEXT: [[MASK2:%.*]] = and i16 [[Y:%.*]], 2
419+ ; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i16 [[MASK2]], 0
420+ ; CHECK-NEXT: [[XOR:%.*]] = xor i1 [[CMP1]], [[CMP2]]
421+ ; CHECK-NEXT: ret i1 [[XOR]]
422+ ;
423+ %mask1 = and i8 %x , 2
424+ %cmp1 = icmp ne i8 %mask1 , 0
425+ %mask2 = and i16 %y , 2
426+ %cmp2 = icmp ne i16 %mask2 , 0
427+ %xor = xor i1 %cmp1 , %cmp2
428+ ret i1 %xor
429+ }
430+
431+ define i1 @test_xor_of_bittest_ne_ne_mask_mismatch (i8 %x , i8 %y ) {
432+ ; CHECK-LABEL: @test_xor_of_bittest_ne_ne_mask_mismatch(
433+ ; CHECK-NEXT: [[MASK1:%.*]] = and i8 [[X:%.*]], 4
434+ ; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i8 [[MASK1]], 0
435+ ; CHECK-NEXT: [[MASK2:%.*]] = and i8 [[Y:%.*]], 2
436+ ; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i8 [[MASK2]], 0
437+ ; CHECK-NEXT: [[XOR:%.*]] = xor i1 [[CMP1]], [[CMP2]]
438+ ; CHECK-NEXT: ret i1 [[XOR]]
439+ ;
440+ %mask1 = and i8 %x , 4
441+ %cmp1 = icmp ne i8 %mask1 , 0
442+ %mask2 = and i8 %y , 2
443+ %cmp2 = icmp ne i8 %mask2 , 0
444+ %xor = xor i1 %cmp1 , %cmp2
445+ ret i1 %xor
446+ }
447+
448+ define i1 @test_xor_of_bittest_ne_ne_nonpower2 (i8 %x , i8 %y ) {
449+ ; CHECK-LABEL: @test_xor_of_bittest_ne_ne_nonpower2(
450+ ; CHECK-NEXT: [[MASK1:%.*]] = and i8 [[X:%.*]], 3
451+ ; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i8 [[MASK1]], 0
452+ ; CHECK-NEXT: [[MASK2:%.*]] = and i8 [[Y:%.*]], 3
453+ ; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i8 [[MASK2]], 0
454+ ; CHECK-NEXT: [[XOR:%.*]] = xor i1 [[CMP1]], [[CMP2]]
455+ ; CHECK-NEXT: ret i1 [[XOR]]
456+ ;
457+ %mask1 = and i8 %x , 3
458+ %cmp1 = icmp ne i8 %mask1 , 0
459+ %mask2 = and i8 %y , 3
460+ %cmp2 = icmp ne i8 %mask2 , 0
461+ %xor = xor i1 %cmp1 , %cmp2
462+ ret i1 %xor
463+ }
464+
465+ define i1 @test_xor_of_bittest_ne_ne_multiuse2 (i8 %x , i8 %y ) {
466+ ; CHECK-LABEL: @test_xor_of_bittest_ne_ne_multiuse2(
467+ ; CHECK-NEXT: [[MASK1:%.*]] = and i8 [[X:%.*]], 2
468+ ; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i8 [[MASK1]], 0
469+ ; CHECK-NEXT: call void @use(i1 [[CMP1]])
470+ ; CHECK-NEXT: [[MASK2:%.*]] = and i8 [[Y:%.*]], 2
471+ ; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i8 [[MASK2]], 0
472+ ; CHECK-NEXT: [[XOR:%.*]] = xor i1 [[CMP1]], [[CMP2]]
473+ ; CHECK-NEXT: ret i1 [[XOR]]
474+ ;
475+ %mask1 = and i8 %x , 2
476+ %cmp1 = icmp ne i8 %mask1 , 0
477+ call void @use (i1 %cmp1 )
478+ %mask2 = and i8 %y , 2
479+ %cmp2 = icmp ne i8 %mask2 , 0
480+ %xor = xor i1 %cmp1 , %cmp2
481+ ret i1 %xor
482+ }
483+
484+ declare void @usei8 (i8 )
0 commit comments