@@ -1401,3 +1401,96 @@ define i32 @sext_maybe_zero(i16 %x) {
14011401 %r = call i32 @llvm.cttz.i32 (i32 %z , i1 false )
14021402 ret i32 %r
14031403}
1404+
1405+ define i32 @xor_known_nonzero_neg_case (i32 %xx ) {
1406+ ; X86-LABEL: xor_known_nonzero_neg_case:
1407+ ; X86: # %bb.0:
1408+ ; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx
1409+ ; X86-NEXT: movl $256, %eax # imm = 0x100
1410+ ; X86-NEXT: shll %cl, %eax
1411+ ; X86-NEXT: rep bsfl %eax, %eax
1412+ ; X86-NEXT: retl
1413+ ;
1414+ ; X64-LABEL: xor_known_nonzero_neg_case:
1415+ ; X64: # %bb.0:
1416+ ; X64-NEXT: movl %edi, %ecx
1417+ ; X64-NEXT: movl $256, %eax # imm = 0x100
1418+ ; X64-NEXT: # kill: def $cl killed $cl killed $ecx
1419+ ; X64-NEXT: shll %cl, %eax
1420+ ; X64-NEXT: rep bsfl %eax, %eax
1421+ ; X64-NEXT: retq
1422+ %x = shl nuw nsw i32 256 , %xx
1423+ %z = xor i32 0 , %x
1424+ %r = call i32 @llvm.cttz.i32 (i32 %z , i1 false )
1425+ ret i32 %r
1426+ }
1427+
1428+ define i32 @xor_known_nonzero_ne_case (i32 %xx , i32 %yy ) {
1429+ ; X86-LABEL: xor_known_nonzero_ne_case:
1430+ ; X86: # %bb.0:
1431+ ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
1432+ ; X86-NEXT: movl %eax, %ecx
1433+ ; X86-NEXT: orl $64, %ecx
1434+ ; X86-NEXT: andl $-65, %eax
1435+ ; X86-NEXT: xorl %ecx, %eax
1436+ ; X86-NEXT: rep bsfl %eax, %eax
1437+ ; X86-NEXT: retl
1438+ ;
1439+ ; X64-LABEL: xor_known_nonzero_ne_case:
1440+ ; X64: # %bb.0:
1441+ ; X64-NEXT: movl %edi, %eax
1442+ ; X64-NEXT: orl $64, %eax
1443+ ; X64-NEXT: andl $-65, %edi
1444+ ; X64-NEXT: xorl %eax, %edi
1445+ ; X64-NEXT: rep bsfl %edi, %eax
1446+ ; X64-NEXT: retq
1447+ %x = or i32 %xx , 64
1448+ %y = and i32 %xx , -65
1449+ %z = xor i32 %y , %x
1450+ %r = call i32 @llvm.cttz.i32 (i32 %z , i1 false )
1451+ ret i32 %r
1452+ }
1453+
1454+ define i32 @xor_maybe_zero (i32 %x ) {
1455+ ; X86-LABEL: xor_maybe_zero:
1456+ ; X86: # %bb.0:
1457+ ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
1458+ ; X86-NEXT: movl %eax, %ecx
1459+ ; X86-NEXT: orl $64, %ecx
1460+ ; X86-NEXT: xorl %eax, %ecx
1461+ ; X86-NEXT: bsfl %ecx, %ecx
1462+ ; X86-NEXT: movl $32, %eax
1463+ ; X86-NEXT: cmovnel %ecx, %eax
1464+ ; X86-NEXT: retl
1465+ ;
1466+ ; X64-LABEL: xor_maybe_zero:
1467+ ; X64: # %bb.0:
1468+ ; X64-NEXT: movl %edi, %ecx
1469+ ; X64-NEXT: orl $64, %ecx
1470+ ; X64-NEXT: xorl %edi, %ecx
1471+ ; X64-NEXT: movl $32, %eax
1472+ ; X64-NEXT: rep bsfl %ecx, %eax
1473+ ; X64-NEXT: retq
1474+ %y = or i32 %x , 64
1475+ %z = xor i32 %y , %x
1476+ %r = call i32 @llvm.cttz.i32 (i32 %z , i1 false )
1477+ ret i32 %r
1478+ }
1479+
1480+ define i32 @xor_maybe_zero2 (i32 %x ) {
1481+ ; X86-LABEL: xor_maybe_zero2:
1482+ ; X86: # %bb.0:
1483+ ; X86-NEXT: bsfl {{[0-9]+}}(%esp), %ecx
1484+ ; X86-NEXT: movl $32, %eax
1485+ ; X86-NEXT: cmovnel %ecx, %eax
1486+ ; X86-NEXT: retl
1487+ ;
1488+ ; X64-LABEL: xor_maybe_zero2:
1489+ ; X64: # %bb.0:
1490+ ; X64-NEXT: movl $32, %eax
1491+ ; X64-NEXT: rep bsfl %edi, %eax
1492+ ; X64-NEXT: retq
1493+ %z = xor i32 0 , %x
1494+ %r = call i32 @llvm.cttz.i32 (i32 %z , i1 false )
1495+ ret i32 %r
1496+ }
0 commit comments