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