1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=x86_64-- | FileCheck %s --check-prefix=X64 3; RUN: llc < %s -mtriple=i686-- | FileCheck %s --check-prefix=X32 4 5define i32 @sub_zext_cmp_mask_same_size_result(i32 %x) { 6; X64-LABEL: sub_zext_cmp_mask_same_size_result: 7; X64: # %bb.0: 8; X64-NEXT: # kill: def $edi killed $edi def $rdi 9; X64-NEXT: andl $1, %edi 10; X64-NEXT: leal -28(%rdi), %eax 11; X64-NEXT: retq 12; 13; X32-LABEL: sub_zext_cmp_mask_same_size_result: 14; X32: # %bb.0: 15; X32-NEXT: movl {{[0-9]+}}(%esp), %eax 16; X32-NEXT: andl $1, %eax 17; X32-NEXT: orl $-28, %eax 18; X32-NEXT: retl 19 %a = and i32 %x, 1 20 %c = icmp eq i32 %a, 0 21 %z = zext i1 %c to i32 22 %r = sub i32 -27, %z 23 ret i32 %r 24} 25 26define i32 @sub_zext_cmp_mask_wider_result(i8 %x) { 27; X64-LABEL: sub_zext_cmp_mask_wider_result: 28; X64: # %bb.0: 29; X64-NEXT: # kill: def $edi killed $edi def $rdi 30; X64-NEXT: andl $1, %edi 31; X64-NEXT: leal 26(%rdi), %eax 32; X64-NEXT: retq 33; 34; X32-LABEL: sub_zext_cmp_mask_wider_result: 35; X32: # %bb.0: 36; X32-NEXT: movzbl {{[0-9]+}}(%esp), %eax 37; X32-NEXT: andl $1, %eax 38; X32-NEXT: orl $26, %eax 39; X32-NEXT: retl 40 %a = and i8 %x, 1 41 %c = icmp eq i8 %a, 0 42 %z = zext i1 %c to i32 43 %r = sub i32 27, %z 44 ret i32 %r 45} 46 47define i8 @sub_zext_cmp_mask_narrower_result(i32 %x) { 48; X64-LABEL: sub_zext_cmp_mask_narrower_result: 49; X64: # %bb.0: 50; X64-NEXT: # kill: def $edi killed $edi def $rdi 51; X64-NEXT: andb $1, %dil 52; X64-NEXT: leal 46(%rdi), %eax 53; X64-NEXT: # kill: def $al killed $al killed $eax 54; X64-NEXT: retq 55; 56; X32-LABEL: sub_zext_cmp_mask_narrower_result: 57; X32: # %bb.0: 58; X32-NEXT: movb {{[0-9]+}}(%esp), %al 59; X32-NEXT: andb $1, %al 60; X32-NEXT: orb $46, %al 61; X32-NEXT: retl 62 %a = and i32 %x, 1 63 %c = icmp eq i32 %a, 0 64 %z = zext i1 %c to i8 65 %r = sub i8 47, %z 66 ret i8 %r 67} 68 69define i8 @add_zext_cmp_mask_same_size_result(i8 %x) { 70; X64-LABEL: add_zext_cmp_mask_same_size_result: 71; X64: # %bb.0: 72; X64-NEXT: movl %edi, %eax 73; X64-NEXT: andb $1, %al 74; X64-NEXT: xorb $27, %al 75; X64-NEXT: # kill: def $al killed $al killed $eax 76; X64-NEXT: retq 77; 78; X32-LABEL: add_zext_cmp_mask_same_size_result: 79; X32: # %bb.0: 80; X32-NEXT: movb {{[0-9]+}}(%esp), %al 81; X32-NEXT: andb $1, %al 82; X32-NEXT: xorb $27, %al 83; X32-NEXT: retl 84 %a = and i8 %x, 1 85 %c = icmp eq i8 %a, 0 86 %z = zext i1 %c to i8 87 %r = add i8 %z, 26 88 ret i8 %r 89} 90 91define i32 @add_zext_cmp_mask_wider_result(i8 %x) { 92; X64-LABEL: add_zext_cmp_mask_wider_result: 93; X64: # %bb.0: 94; X64-NEXT: movl %edi, %eax 95; X64-NEXT: andl $1, %eax 96; X64-NEXT: xorl $27, %eax 97; X64-NEXT: retq 98; 99; X32-LABEL: add_zext_cmp_mask_wider_result: 100; X32: # %bb.0: 101; X32-NEXT: movzbl {{[0-9]+}}(%esp), %eax 102; X32-NEXT: andl $1, %eax 103; X32-NEXT: xorl $27, %eax 104; X32-NEXT: retl 105 %a = and i8 %x, 1 106 %c = icmp eq i8 %a, 0 107 %z = zext i1 %c to i32 108 %r = add i32 %z, 26 109 ret i32 %r 110} 111 112define i8 @add_zext_cmp_mask_narrower_result(i32 %x) { 113; X64-LABEL: add_zext_cmp_mask_narrower_result: 114; X64: # %bb.0: 115; X64-NEXT: movl %edi, %eax 116; X64-NEXT: andb $1, %al 117; X64-NEXT: xorb $43, %al 118; X64-NEXT: # kill: def $al killed $al killed $eax 119; X64-NEXT: retq 120; 121; X32-LABEL: add_zext_cmp_mask_narrower_result: 122; X32: # %bb.0: 123; X32-NEXT: movb {{[0-9]+}}(%esp), %al 124; X32-NEXT: andb $1, %al 125; X32-NEXT: xorb $43, %al 126; X32-NEXT: retl 127 %a = and i32 %x, 1 128 %c = icmp eq i32 %a, 0 129 %z = zext i1 %c to i8 130 %r = add i8 %z, 42 131 ret i8 %r 132} 133 134define i32 @low_bit_select_constants_bigger_false_same_size_result(i32 %x) { 135; X64-LABEL: low_bit_select_constants_bigger_false_same_size_result: 136; X64: # %bb.0: 137; X64-NEXT: # kill: def $edi killed $edi def $rdi 138; X64-NEXT: andl $1, %edi 139; X64-NEXT: leal 42(%rdi), %eax 140; X64-NEXT: retq 141; 142; X32-LABEL: low_bit_select_constants_bigger_false_same_size_result: 143; X32: # %bb.0: 144; X32-NEXT: movl {{[0-9]+}}(%esp), %eax 145; X32-NEXT: andl $1, %eax 146; X32-NEXT: orl $42, %eax 147; X32-NEXT: retl 148 %a = and i32 %x, 1 149 %c = icmp eq i32 %a, 0 150 %r = select i1 %c, i32 42, i32 43 151 ret i32 %r 152} 153 154define i64 @low_bit_select_constants_bigger_false_wider_result(i32 %x) { 155; X64-LABEL: low_bit_select_constants_bigger_false_wider_result: 156; X64: # %bb.0: 157; X64-NEXT: # kill: def $edi killed $edi def $rdi 158; X64-NEXT: andl $1, %edi 159; X64-NEXT: leaq 26(%rdi), %rax 160; X64-NEXT: retq 161; 162; X32-LABEL: low_bit_select_constants_bigger_false_wider_result: 163; X32: # %bb.0: 164; X32-NEXT: movl {{[0-9]+}}(%esp), %eax 165; X32-NEXT: andl $1, %eax 166; X32-NEXT: orl $26, %eax 167; X32-NEXT: xorl %edx, %edx 168; X32-NEXT: retl 169 %a = and i32 %x, 1 170 %c = icmp eq i32 %a, 0 171 %r = select i1 %c, i64 26, i64 27 172 ret i64 %r 173} 174 175define i16 @low_bit_select_constants_bigger_false_narrower_result(i32 %x) { 176; X64-LABEL: low_bit_select_constants_bigger_false_narrower_result: 177; X64: # %bb.0: 178; X64-NEXT: # kill: def $edi killed $edi def $rdi 179; X64-NEXT: andl $1, %edi 180; X64-NEXT: leal 36(%rdi), %eax 181; X64-NEXT: # kill: def $ax killed $ax killed $eax 182; X64-NEXT: retq 183; 184; X32-LABEL: low_bit_select_constants_bigger_false_narrower_result: 185; X32: # %bb.0: 186; X32-NEXT: movzwl {{[0-9]+}}(%esp), %eax 187; X32-NEXT: andl $1, %eax 188; X32-NEXT: orl $36, %eax 189; X32-NEXT: # kill: def $ax killed $ax killed $eax 190; X32-NEXT: retl 191 %a = and i32 %x, 1 192 %c = icmp eq i32 %a, 0 193 %r = select i1 %c, i16 36, i16 37 194 ret i16 %r 195} 196 197define i8 @low_bit_select_constants_bigger_true_same_size_result(i8 %x) { 198; X64-LABEL: low_bit_select_constants_bigger_true_same_size_result: 199; X64: # %bb.0: 200; X64-NEXT: movl %edi, %eax 201; X64-NEXT: andb $1, %al 202; X64-NEXT: xorb $-29, %al 203; X64-NEXT: # kill: def $al killed $al killed $eax 204; X64-NEXT: retq 205; 206; X32-LABEL: low_bit_select_constants_bigger_true_same_size_result: 207; X32: # %bb.0: 208; X32-NEXT: movb {{[0-9]+}}(%esp), %al 209; X32-NEXT: andb $1, %al 210; X32-NEXT: xorb $-29, %al 211; X32-NEXT: retl 212 %a = and i8 %x, 1 213 %c = icmp eq i8 %a, 0 214 %r = select i1 %c, i8 227, i8 226 215 ret i8 %r 216} 217 218define i32 @low_bit_select_constants_bigger_true_wider_result(i8 %x) { 219; X64-LABEL: low_bit_select_constants_bigger_true_wider_result: 220; X64: # %bb.0: 221; X64-NEXT: movl %edi, %eax 222; X64-NEXT: andl $1, %eax 223; X64-NEXT: xorl $227, %eax 224; X64-NEXT: retq 225; 226; X32-LABEL: low_bit_select_constants_bigger_true_wider_result: 227; X32: # %bb.0: 228; X32-NEXT: movzbl {{[0-9]+}}(%esp), %eax 229; X32-NEXT: andl $1, %eax 230; X32-NEXT: xorl $227, %eax 231; X32-NEXT: retl 232 %a = and i8 %x, 1 233 %c = icmp eq i8 %a, 0 234 %r = select i1 %c, i32 227, i32 226 235 ret i32 %r 236} 237 238define i8 @low_bit_select_constants_bigger_true_narrower_result(i16 %x) { 239; X64-LABEL: low_bit_select_constants_bigger_true_narrower_result: 240; X64: # %bb.0: 241; X64-NEXT: movl %edi, %eax 242; X64-NEXT: andb $1, %al 243; X64-NEXT: xorb $41, %al 244; X64-NEXT: # kill: def $al killed $al killed $eax 245; X64-NEXT: retq 246; 247; X32-LABEL: low_bit_select_constants_bigger_true_narrower_result: 248; X32: # %bb.0: 249; X32-NEXT: movb {{[0-9]+}}(%esp), %al 250; X32-NEXT: andb $1, %al 251; X32-NEXT: xorb $41, %al 252; X32-NEXT: retl 253 %a = and i16 %x, 1 254 %c = icmp eq i16 %a, 0 255 %r = select i1 %c, i8 41, i8 40 256 ret i8 %r 257} 258 259; Truncation hoisting must not occur with opaque constants 260; because that can induce infinite looping. 261 262define i1 @opaque_constant(i48 %x, i48 %y) { 263; X64-LABEL: opaque_constant: 264; X64: # %bb.0: 265; X64-NEXT: movq %rsi, %rax 266; X64-NEXT: shrq $32, %rdi 267; X64-NEXT: shrq $32, %rax 268; X64-NEXT: xorl %edi, %eax 269; X64-NEXT: andl $1, %eax 270; X64-NEXT: # kill: def $al killed $al killed $rax 271; X64-NEXT: retq 272; 273; X32-LABEL: opaque_constant: 274; X32: # %bb.0: 275; X32-NEXT: movl {{[0-9]+}}(%esp), %eax 276; X32-NEXT: xorl {{[0-9]+}}(%esp), %eax 277; X32-NEXT: andl $1, %eax 278; X32-NEXT: # kill: def $al killed $al killed $eax 279; X32-NEXT: retl 280 %andx = and i48 %x, 4294967296 281 %andy = and i48 %y, 4294967296 282 %cmp1 = icmp ne i48 %andx, 0 283 %cmp2 = icmp ne i48 %andy, 0 284 %r = xor i1 %cmp1, %cmp2 285 ret i1 %r 286} 287 288