1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=i686-- -mattr=sse2 | FileCheck %s --check-prefixes=ANY,X32-SSE2 3; RUN: llc < %s -mtriple=x86_64-- -mattr=avx2 | FileCheck %s --check-prefixes=ANY,X64-AVX2 4 5declare i8 @llvm.fshl.i8(i8, i8, i8) 6declare i16 @llvm.fshl.i16(i16, i16, i16) 7declare i32 @llvm.fshl.i32(i32, i32, i32) 8declare i64 @llvm.fshl.i64(i64, i64, i64) 9declare <4 x i32> @llvm.fshl.v4i32(<4 x i32>, <4 x i32>, <4 x i32>) 10 11declare i8 @llvm.fshr.i8(i8, i8, i8) 12declare i16 @llvm.fshr.i16(i16, i16, i16) 13declare i32 @llvm.fshr.i32(i32, i32, i32) 14declare i64 @llvm.fshr.i64(i64, i64, i64) 15declare <4 x i32> @llvm.fshr.v4i32(<4 x i32>, <4 x i32>, <4 x i32>) 16 17; General case - all operands can be variables 18 19define i32 @fshl_i32(i32 %x, i32 %y, i32 %z) nounwind { 20; X32-SSE2-LABEL: fshl_i32: 21; X32-SSE2: # %bb.0: 22; X32-SSE2-NEXT: movb {{[0-9]+}}(%esp), %cl 23; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %edx 24; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax 25; X32-SSE2-NEXT: shldl %cl, %edx, %eax 26; X32-SSE2-NEXT: retl 27; 28; X64-AVX2-LABEL: fshl_i32: 29; X64-AVX2: # %bb.0: 30; X64-AVX2-NEXT: movl %edx, %ecx 31; X64-AVX2-NEXT: movl %edi, %eax 32; X64-AVX2-NEXT: # kill: def $cl killed $cl killed $ecx 33; X64-AVX2-NEXT: shldl %cl, %esi, %eax 34; X64-AVX2-NEXT: retq 35 %f = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 %z) 36 ret i32 %f 37} 38 39; Verify that weird types are minimally supported. 40declare i37 @llvm.fshl.i37(i37, i37, i37) 41define i37 @fshl_i37(i37 %x, i37 %y, i37 %z) nounwind { 42; X32-SSE2-LABEL: fshl_i37: 43; X32-SSE2: # %bb.0: 44; X32-SSE2-NEXT: pushl %ebp 45; X32-SSE2-NEXT: pushl %ebx 46; X32-SSE2-NEXT: pushl %edi 47; X32-SSE2-NEXT: pushl %esi 48; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %esi 49; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %ebx 50; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %edi 51; X32-SSE2-NEXT: shldl $27, %ebx, %edi 52; X32-SSE2-NEXT: shll $27, %ebx 53; X32-SSE2-NEXT: shrdl $1, %edi, %ebx 54; X32-SSE2-NEXT: shrl %edi 55; X32-SSE2-NEXT: pushl $0 56; X32-SSE2-NEXT: pushl $37 57; X32-SSE2-NEXT: pushl {{[0-9]+}}(%esp) 58; X32-SSE2-NEXT: pushl {{[0-9]+}}(%esp) 59; X32-SSE2-NEXT: calll __umoddi3 60; X32-SSE2-NEXT: addl $16, %esp 61; X32-SSE2-NEXT: movl %eax, %edx 62; X32-SSE2-NEXT: movl %edx, %ecx 63; X32-SSE2-NEXT: notb %cl 64; X32-SSE2-NEXT: shrdl %cl, %edi, %ebx 65; X32-SSE2-NEXT: shrl %cl, %edi 66; X32-SSE2-NEXT: xorl %eax, %eax 67; X32-SSE2-NEXT: testb $32, %cl 68; X32-SSE2-NEXT: cmovnel %edi, %ebx 69; X32-SSE2-NEXT: cmovnel %eax, %edi 70; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax 71; X32-SSE2-NEXT: movl %edx, %ecx 72; X32-SSE2-NEXT: shll %cl, %eax 73; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %ebp 74; X32-SSE2-NEXT: shldl %cl, %ebp, %esi 75; X32-SSE2-NEXT: testb $32, %dl 76; X32-SSE2-NEXT: cmovnel %eax, %esi 77; X32-SSE2-NEXT: movl $0, %ecx 78; X32-SSE2-NEXT: cmovnel %ecx, %eax 79; X32-SSE2-NEXT: orl %ebx, %eax 80; X32-SSE2-NEXT: orl %edi, %esi 81; X32-SSE2-NEXT: movl %esi, %edx 82; X32-SSE2-NEXT: popl %esi 83; X32-SSE2-NEXT: popl %edi 84; X32-SSE2-NEXT: popl %ebx 85; X32-SSE2-NEXT: popl %ebp 86; X32-SSE2-NEXT: retl 87; 88; X64-AVX2-LABEL: fshl_i37: 89; X64-AVX2: # %bb.0: 90; X64-AVX2-NEXT: movq %rdx, %rcx 91; X64-AVX2-NEXT: movabsq $-2492803253203993461, %rdx # imm = 0xDD67C8A60DD67C8B 92; X64-AVX2-NEXT: movq %rcx, %rax 93; X64-AVX2-NEXT: mulq %rdx 94; X64-AVX2-NEXT: shrq $5, %rdx 95; X64-AVX2-NEXT: leal (%rdx,%rdx,8), %eax 96; X64-AVX2-NEXT: leal (%rdx,%rax,4), %eax 97; X64-AVX2-NEXT: subl %eax, %ecx 98; X64-AVX2-NEXT: shlq $27, %rsi 99; X64-AVX2-NEXT: # kill: def $cl killed $cl killed $rcx 100; X64-AVX2-NEXT: shldq %cl, %rsi, %rdi 101; X64-AVX2-NEXT: movq %rdi, %rax 102; X64-AVX2-NEXT: retq 103 %f = call i37 @llvm.fshl.i37(i37 %x, i37 %y, i37 %z) 104 ret i37 %f 105} 106 107; extract(concat(0b1110000, 0b1111111) << 2) = 0b1000011 108 109declare i7 @llvm.fshl.i7(i7, i7, i7) 110define i7 @fshl_i7_const_fold() { 111; ANY-LABEL: fshl_i7_const_fold: 112; ANY: # %bb.0: 113; ANY-NEXT: movb $67, %al 114; ANY-NEXT: ret{{[l|q]}} 115 %f = call i7 @llvm.fshl.i7(i7 112, i7 127, i7 2) 116 ret i7 %f 117} 118 119; With constant shift amount, this is 'shld' with constant operand. 120 121define i32 @fshl_i32_const_shift(i32 %x, i32 %y) nounwind { 122; X32-SSE2-LABEL: fshl_i32_const_shift: 123; X32-SSE2: # %bb.0: 124; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %ecx 125; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax 126; X32-SSE2-NEXT: shldl $9, %ecx, %eax 127; X32-SSE2-NEXT: retl 128; 129; X64-AVX2-LABEL: fshl_i32_const_shift: 130; X64-AVX2: # %bb.0: 131; X64-AVX2-NEXT: movl %edi, %eax 132; X64-AVX2-NEXT: shldl $9, %esi, %eax 133; X64-AVX2-NEXT: retq 134 %f = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 9) 135 ret i32 %f 136} 137 138; Check modulo math on shift amount. 139 140define i32 @fshl_i32_const_overshift(i32 %x, i32 %y) nounwind { 141; X32-SSE2-LABEL: fshl_i32_const_overshift: 142; X32-SSE2: # %bb.0: 143; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %ecx 144; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax 145; X32-SSE2-NEXT: shldl $9, %ecx, %eax 146; X32-SSE2-NEXT: retl 147; 148; X64-AVX2-LABEL: fshl_i32_const_overshift: 149; X64-AVX2: # %bb.0: 150; X64-AVX2-NEXT: movl %edi, %eax 151; X64-AVX2-NEXT: shldl $9, %esi, %eax 152; X64-AVX2-NEXT: retq 153 %f = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 41) 154 ret i32 %f 155} 156 157; 64-bit should also work. 158 159define i64 @fshl_i64_const_overshift(i64 %x, i64 %y) nounwind { 160; X32-SSE2-LABEL: fshl_i64_const_overshift: 161; X32-SSE2: # %bb.0: 162; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax 163; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %ecx 164; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %edx 165; X32-SSE2-NEXT: shldl $9, %ecx, %edx 166; X32-SSE2-NEXT: shrdl $23, %ecx, %eax 167; X32-SSE2-NEXT: retl 168; 169; X64-AVX2-LABEL: fshl_i64_const_overshift: 170; X64-AVX2: # %bb.0: 171; X64-AVX2-NEXT: movq %rdi, %rax 172; X64-AVX2-NEXT: shldq $41, %rsi, %rax 173; X64-AVX2-NEXT: retq 174 %f = call i64 @llvm.fshl.i64(i64 %x, i64 %y, i64 105) 175 ret i64 %f 176} 177 178; This should work without any node-specific logic. 179 180define i8 @fshl_i8_const_fold() nounwind { 181; ANY-LABEL: fshl_i8_const_fold: 182; ANY: # %bb.0: 183; ANY-NEXT: movb $-128, %al 184; ANY-NEXT: ret{{[l|q]}} 185 %f = call i8 @llvm.fshl.i8(i8 255, i8 0, i8 7) 186 ret i8 %f 187} 188 189; Repeat everything for funnel shift right. 190 191; General case - all operands can be variables 192 193define i32 @fshr_i32(i32 %x, i32 %y, i32 %z) nounwind { 194; X32-SSE2-LABEL: fshr_i32: 195; X32-SSE2: # %bb.0: 196; X32-SSE2-NEXT: movb {{[0-9]+}}(%esp), %cl 197; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %edx 198; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax 199; X32-SSE2-NEXT: shrdl %cl, %edx, %eax 200; X32-SSE2-NEXT: retl 201; 202; X64-AVX2-LABEL: fshr_i32: 203; X64-AVX2: # %bb.0: 204; X64-AVX2-NEXT: movl %edx, %ecx 205; X64-AVX2-NEXT: movl %esi, %eax 206; X64-AVX2-NEXT: # kill: def $cl killed $cl killed $ecx 207; X64-AVX2-NEXT: shrdl %cl, %edi, %eax 208; X64-AVX2-NEXT: retq 209 %f = call i32 @llvm.fshr.i32(i32 %x, i32 %y, i32 %z) 210 ret i32 %f 211} 212 213; Verify that weird types are minimally supported. 214declare i37 @llvm.fshr.i37(i37, i37, i37) 215define i37 @fshr_i37(i37 %x, i37 %y, i37 %z) nounwind { 216; X32-SSE2-LABEL: fshr_i37: 217; X32-SSE2: # %bb.0: 218; X32-SSE2-NEXT: pushl %ebp 219; X32-SSE2-NEXT: pushl %ebx 220; X32-SSE2-NEXT: pushl %edi 221; X32-SSE2-NEXT: pushl %esi 222; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %ebp 223; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %ebx 224; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %edi 225; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %esi 226; X32-SSE2-NEXT: shldl $1, %edi, %esi 227; X32-SSE2-NEXT: addl %edi, %edi 228; X32-SSE2-NEXT: pushl $0 229; X32-SSE2-NEXT: pushl $37 230; X32-SSE2-NEXT: pushl {{[0-9]+}}(%esp) 231; X32-SSE2-NEXT: pushl {{[0-9]+}}(%esp) 232; X32-SSE2-NEXT: calll __umoddi3 233; X32-SSE2-NEXT: addl $16, %esp 234; X32-SSE2-NEXT: addb $27, %al 235; X32-SSE2-NEXT: movl %eax, %edx 236; X32-SSE2-NEXT: notb %dl 237; X32-SSE2-NEXT: movl %edx, %ecx 238; X32-SSE2-NEXT: shldl %cl, %edi, %esi 239; X32-SSE2-NEXT: shldl $27, %ebp, %ebx 240; X32-SSE2-NEXT: shll $27, %ebp 241; X32-SSE2-NEXT: movl %eax, %ecx 242; X32-SSE2-NEXT: shrdl %cl, %ebx, %ebp 243; X32-SSE2-NEXT: shrl %cl, %ebx 244; X32-SSE2-NEXT: xorl %ecx, %ecx 245; X32-SSE2-NEXT: testb $32, %al 246; X32-SSE2-NEXT: cmovnel %ebx, %ebp 247; X32-SSE2-NEXT: cmovnel %ecx, %ebx 248; X32-SSE2-NEXT: xorl %eax, %eax 249; X32-SSE2-NEXT: movl %edx, %ecx 250; X32-SSE2-NEXT: shll %cl, %edi 251; X32-SSE2-NEXT: testb $32, %dl 252; X32-SSE2-NEXT: cmovnel %edi, %esi 253; X32-SSE2-NEXT: cmovnel %eax, %edi 254; X32-SSE2-NEXT: orl %ebp, %edi 255; X32-SSE2-NEXT: orl %ebx, %esi 256; X32-SSE2-NEXT: movl %edi, %eax 257; X32-SSE2-NEXT: movl %esi, %edx 258; X32-SSE2-NEXT: popl %esi 259; X32-SSE2-NEXT: popl %edi 260; X32-SSE2-NEXT: popl %ebx 261; X32-SSE2-NEXT: popl %ebp 262; X32-SSE2-NEXT: retl 263; 264; X64-AVX2-LABEL: fshr_i37: 265; X64-AVX2: # %bb.0: 266; X64-AVX2-NEXT: movq %rdx, %rcx 267; X64-AVX2-NEXT: movabsq $-2492803253203993461, %rdx # imm = 0xDD67C8A60DD67C8B 268; X64-AVX2-NEXT: movq %rcx, %rax 269; X64-AVX2-NEXT: mulq %rdx 270; X64-AVX2-NEXT: shrq $5, %rdx 271; X64-AVX2-NEXT: leal (%rdx,%rdx,8), %eax 272; X64-AVX2-NEXT: leal (%rdx,%rax,4), %eax 273; X64-AVX2-NEXT: subl %eax, %ecx 274; X64-AVX2-NEXT: addl $27, %ecx 275; X64-AVX2-NEXT: shlq $27, %rsi 276; X64-AVX2-NEXT: # kill: def $cl killed $cl killed $rcx 277; X64-AVX2-NEXT: shrdq %cl, %rdi, %rsi 278; X64-AVX2-NEXT: movq %rsi, %rax 279; X64-AVX2-NEXT: retq 280 %f = call i37 @llvm.fshr.i37(i37 %x, i37 %y, i37 %z) 281 ret i37 %f 282} 283 284; extract(concat(0b1110000, 0b1111111) >> 2) = 0b0011111 285 286declare i7 @llvm.fshr.i7(i7, i7, i7) 287define i7 @fshr_i7_const_fold() nounwind { 288; ANY-LABEL: fshr_i7_const_fold: 289; ANY: # %bb.0: 290; ANY-NEXT: movb $31, %al 291; ANY-NEXT: ret{{[l|q]}} 292 %f = call i7 @llvm.fshr.i7(i7 112, i7 127, i7 2) 293 ret i7 %f 294} 295 296; demanded bits tests 297 298define i32 @fshl_i32_demandedbits(i32 %a0, i32 %a1) nounwind { 299; X32-SSE2-LABEL: fshl_i32_demandedbits: 300; X32-SSE2: # %bb.0: 301; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %ecx 302; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax 303; X32-SSE2-NEXT: shldl $9, %ecx, %eax 304; X32-SSE2-NEXT: retl 305; 306; X64-AVX2-LABEL: fshl_i32_demandedbits: 307; X64-AVX2: # %bb.0: 308; X64-AVX2-NEXT: movl %edi, %eax 309; X64-AVX2-NEXT: shldl $9, %esi, %eax 310; X64-AVX2-NEXT: retq 311 %x = or i32 %a0, 2147483648 312 %y = or i32 %a1, 1 313 %res = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 9) 314 ret i32 %res 315} 316 317define i32 @fshr_i32_demandedbits(i32 %a0, i32 %a1) nounwind { 318; X32-SSE2-LABEL: fshr_i32_demandedbits: 319; X32-SSE2: # %bb.0: 320; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %ecx 321; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax 322; X32-SSE2-NEXT: shrdl $9, %ecx, %eax 323; X32-SSE2-NEXT: retl 324; 325; X64-AVX2-LABEL: fshr_i32_demandedbits: 326; X64-AVX2: # %bb.0: 327; X64-AVX2-NEXT: movl %edi, %eax 328; X64-AVX2-NEXT: shldl $23, %esi, %eax 329; X64-AVX2-NEXT: retq 330 %x = or i32 %a0, 2147483648 331 %y = or i32 %a1, 1 332 %res = call i32 @llvm.fshr.i32(i32 %x, i32 %y, i32 9) 333 ret i32 %res 334} 335 336; undef handling 337 338define i32 @fshl_i32_undef0(i32 %a0, i32 %a1) nounwind { 339; X32-SSE2-LABEL: fshl_i32_undef0: 340; X32-SSE2: # %bb.0: 341; X32-SSE2-NEXT: movb {{[0-9]+}}(%esp), %cl 342; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax 343; X32-SSE2-NEXT: shldl %cl, %eax, %eax 344; X32-SSE2-NEXT: retl 345; 346; X64-AVX2-LABEL: fshl_i32_undef0: 347; X64-AVX2: # %bb.0: 348; X64-AVX2-NEXT: movl %esi, %ecx 349; X64-AVX2-NEXT: # kill: def $cl killed $cl killed $ecx 350; X64-AVX2-NEXT: shldl %cl, %edi, %eax 351; X64-AVX2-NEXT: retq 352 %res = call i32 @llvm.fshl.i32(i32 undef, i32 %a0, i32 %a1) 353 ret i32 %res 354} 355 356define i32 @fshl_i32_undef0_msk(i32 %a0, i32 %a1) nounwind { 357; X32-SSE2-LABEL: fshl_i32_undef0_msk: 358; X32-SSE2: # %bb.0: 359; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax 360; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %ecx 361; X32-SSE2-NEXT: andl $7, %ecx 362; X32-SSE2-NEXT: # kill: def $cl killed $cl killed $ecx 363; X32-SSE2-NEXT: shldl %cl, %eax, %eax 364; X32-SSE2-NEXT: retl 365; 366; X64-AVX2-LABEL: fshl_i32_undef0_msk: 367; X64-AVX2: # %bb.0: 368; X64-AVX2-NEXT: movl %esi, %ecx 369; X64-AVX2-NEXT: andl $7, %ecx 370; X64-AVX2-NEXT: # kill: def $cl killed $cl killed $ecx 371; X64-AVX2-NEXT: shldl %cl, %edi, %eax 372; X64-AVX2-NEXT: retq 373 %m = and i32 %a1, 7 374 %res = call i32 @llvm.fshl.i32(i32 undef, i32 %a0, i32 %m) 375 ret i32 %res 376} 377 378define i32 @fshl_i32_undef0_cst(i32 %a0) nounwind { 379; X32-SSE2-LABEL: fshl_i32_undef0_cst: 380; X32-SSE2: # %bb.0: 381; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax 382; X32-SSE2-NEXT: shrl $23, %eax 383; X32-SSE2-NEXT: retl 384; 385; X64-AVX2-LABEL: fshl_i32_undef0_cst: 386; X64-AVX2: # %bb.0: 387; X64-AVX2-NEXT: movl %edi, %eax 388; X64-AVX2-NEXT: shrl $23, %eax 389; X64-AVX2-NEXT: retq 390 %res = call i32 @llvm.fshl.i32(i32 undef, i32 %a0, i32 9) 391 ret i32 %res 392} 393 394define i32 @fshl_i32_undef1(i32 %a0, i32 %a1) nounwind { 395; X32-SSE2-LABEL: fshl_i32_undef1: 396; X32-SSE2: # %bb.0: 397; X32-SSE2-NEXT: movb {{[0-9]+}}(%esp), %cl 398; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax 399; X32-SSE2-NEXT: shldl %cl, %eax, %eax 400; X32-SSE2-NEXT: retl 401; 402; X64-AVX2-LABEL: fshl_i32_undef1: 403; X64-AVX2: # %bb.0: 404; X64-AVX2-NEXT: movl %esi, %ecx 405; X64-AVX2-NEXT: movl %edi, %eax 406; X64-AVX2-NEXT: # kill: def $cl killed $cl killed $ecx 407; X64-AVX2-NEXT: shldl %cl, %eax, %eax 408; X64-AVX2-NEXT: retq 409 %res = call i32 @llvm.fshl.i32(i32 %a0, i32 undef, i32 %a1) 410 ret i32 %res 411} 412 413define i32 @fshl_i32_undef1_msk(i32 %a0, i32 %a1) nounwind { 414; X32-SSE2-LABEL: fshl_i32_undef1_msk: 415; X32-SSE2: # %bb.0: 416; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax 417; X32-SSE2-NEXT: movb {{[0-9]+}}(%esp), %cl 418; X32-SSE2-NEXT: andb $7, %cl 419; X32-SSE2-NEXT: shll %cl, %eax 420; X32-SSE2-NEXT: retl 421; 422; X64-AVX2-LABEL: fshl_i32_undef1_msk: 423; X64-AVX2: # %bb.0: 424; X64-AVX2-NEXT: movl %esi, %ecx 425; X64-AVX2-NEXT: movl %edi, %eax 426; X64-AVX2-NEXT: andb $7, %cl 427; X64-AVX2-NEXT: # kill: def $cl killed $cl killed $ecx 428; X64-AVX2-NEXT: shll %cl, %eax 429; X64-AVX2-NEXT: retq 430 %m = and i32 %a1, 7 431 %res = call i32 @llvm.fshl.i32(i32 %a0, i32 undef, i32 %m) 432 ret i32 %res 433} 434 435define i32 @fshl_i32_undef1_cst(i32 %a0) nounwind { 436; X32-SSE2-LABEL: fshl_i32_undef1_cst: 437; X32-SSE2: # %bb.0: 438; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax 439; X32-SSE2-NEXT: shll $9, %eax 440; X32-SSE2-NEXT: retl 441; 442; X64-AVX2-LABEL: fshl_i32_undef1_cst: 443; X64-AVX2: # %bb.0: 444; X64-AVX2-NEXT: movl %edi, %eax 445; X64-AVX2-NEXT: shll $9, %eax 446; X64-AVX2-NEXT: retq 447 %res = call i32 @llvm.fshl.i32(i32 %a0, i32 undef, i32 9) 448 ret i32 %res 449} 450 451define i32 @fshl_i32_undef2(i32 %a0, i32 %a1) nounwind { 452; X32-SSE2-LABEL: fshl_i32_undef2: 453; X32-SSE2: # %bb.0: 454; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %ecx 455; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax 456; X32-SSE2-NEXT: shldl %cl, %ecx, %eax 457; X32-SSE2-NEXT: retl 458; 459; X64-AVX2-LABEL: fshl_i32_undef2: 460; X64-AVX2: # %bb.0: 461; X64-AVX2-NEXT: movl %edi, %eax 462; X64-AVX2-NEXT: shldl %cl, %esi, %eax 463; X64-AVX2-NEXT: retq 464 %res = call i32 @llvm.fshl.i32(i32 %a0, i32 %a1, i32 undef) 465 ret i32 %res 466} 467 468define i32 @fshr_i32_undef0(i32 %a0, i32 %a1) nounwind { 469; X32-SSE2-LABEL: fshr_i32_undef0: 470; X32-SSE2: # %bb.0: 471; X32-SSE2-NEXT: movb {{[0-9]+}}(%esp), %cl 472; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax 473; X32-SSE2-NEXT: shrdl %cl, %eax, %eax 474; X32-SSE2-NEXT: retl 475; 476; X64-AVX2-LABEL: fshr_i32_undef0: 477; X64-AVX2: # %bb.0: 478; X64-AVX2-NEXT: movl %esi, %ecx 479; X64-AVX2-NEXT: movl %edi, %eax 480; X64-AVX2-NEXT: # kill: def $cl killed $cl killed $ecx 481; X64-AVX2-NEXT: shrdl %cl, %eax, %eax 482; X64-AVX2-NEXT: retq 483 %res = call i32 @llvm.fshr.i32(i32 undef, i32 %a0, i32 %a1) 484 ret i32 %res 485} 486 487define i32 @fshr_i32_undef0_msk(i32 %a0, i32 %a1) nounwind { 488; X32-SSE2-LABEL: fshr_i32_undef0_msk: 489; X32-SSE2: # %bb.0: 490; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax 491; X32-SSE2-NEXT: movb {{[0-9]+}}(%esp), %cl 492; X32-SSE2-NEXT: andb $7, %cl 493; X32-SSE2-NEXT: shrl %cl, %eax 494; X32-SSE2-NEXT: retl 495; 496; X64-AVX2-LABEL: fshr_i32_undef0_msk: 497; X64-AVX2: # %bb.0: 498; X64-AVX2-NEXT: movl %esi, %ecx 499; X64-AVX2-NEXT: movl %edi, %eax 500; X64-AVX2-NEXT: andb $7, %cl 501; X64-AVX2-NEXT: # kill: def $cl killed $cl killed $ecx 502; X64-AVX2-NEXT: shrl %cl, %eax 503; X64-AVX2-NEXT: retq 504 %m = and i32 %a1, 7 505 %res = call i32 @llvm.fshr.i32(i32 undef, i32 %a0, i32 %m) 506 ret i32 %res 507} 508 509define i32 @fshr_i32_undef0_cst(i32 %a0) nounwind { 510; X32-SSE2-LABEL: fshr_i32_undef0_cst: 511; X32-SSE2: # %bb.0: 512; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax 513; X32-SSE2-NEXT: shrl $9, %eax 514; X32-SSE2-NEXT: retl 515; 516; X64-AVX2-LABEL: fshr_i32_undef0_cst: 517; X64-AVX2: # %bb.0: 518; X64-AVX2-NEXT: movl %edi, %eax 519; X64-AVX2-NEXT: shrl $9, %eax 520; X64-AVX2-NEXT: retq 521 %res = call i32 @llvm.fshr.i32(i32 undef, i32 %a0, i32 9) 522 ret i32 %res 523} 524 525define i32 @fshr_i32_undef1(i32 %a0, i32 %a1) nounwind { 526; X32-SSE2-LABEL: fshr_i32_undef1: 527; X32-SSE2: # %bb.0: 528; X32-SSE2-NEXT: movb {{[0-9]+}}(%esp), %cl 529; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax 530; X32-SSE2-NEXT: shrdl %cl, %eax, %eax 531; X32-SSE2-NEXT: retl 532; 533; X64-AVX2-LABEL: fshr_i32_undef1: 534; X64-AVX2: # %bb.0: 535; X64-AVX2-NEXT: movl %esi, %ecx 536; X64-AVX2-NEXT: # kill: def $cl killed $cl killed $ecx 537; X64-AVX2-NEXT: shrdl %cl, %edi, %eax 538; X64-AVX2-NEXT: retq 539 %res = call i32 @llvm.fshr.i32(i32 %a0, i32 undef, i32 %a1) 540 ret i32 %res 541} 542 543define i32 @fshr_i32_undef1_msk(i32 %a0, i32 %a1) nounwind { 544; X32-SSE2-LABEL: fshr_i32_undef1_msk: 545; X32-SSE2: # %bb.0: 546; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax 547; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %ecx 548; X32-SSE2-NEXT: andl $7, %ecx 549; X32-SSE2-NEXT: # kill: def $cl killed $cl killed $ecx 550; X32-SSE2-NEXT: shrdl %cl, %eax, %eax 551; X32-SSE2-NEXT: retl 552; 553; X64-AVX2-LABEL: fshr_i32_undef1_msk: 554; X64-AVX2: # %bb.0: 555; X64-AVX2-NEXT: movl %esi, %ecx 556; X64-AVX2-NEXT: andl $7, %ecx 557; X64-AVX2-NEXT: # kill: def $cl killed $cl killed $ecx 558; X64-AVX2-NEXT: shrdl %cl, %edi, %eax 559; X64-AVX2-NEXT: retq 560 %m = and i32 %a1, 7 561 %res = call i32 @llvm.fshr.i32(i32 %a0, i32 undef, i32 %m) 562 ret i32 %res 563} 564 565define i32 @fshr_i32_undef1_cst(i32 %a0) nounwind { 566; X32-SSE2-LABEL: fshr_i32_undef1_cst: 567; X32-SSE2: # %bb.0: 568; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax 569; X32-SSE2-NEXT: shll $23, %eax 570; X32-SSE2-NEXT: retl 571; 572; X64-AVX2-LABEL: fshr_i32_undef1_cst: 573; X64-AVX2: # %bb.0: 574; X64-AVX2-NEXT: movl %edi, %eax 575; X64-AVX2-NEXT: shll $23, %eax 576; X64-AVX2-NEXT: retq 577 %res = call i32 @llvm.fshr.i32(i32 %a0, i32 undef, i32 9) 578 ret i32 %res 579} 580 581define i32 @fshr_i32_undef2(i32 %a0, i32 %a1) nounwind { 582; X32-SSE2-LABEL: fshr_i32_undef2: 583; X32-SSE2: # %bb.0: 584; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %ecx 585; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax 586; X32-SSE2-NEXT: shrdl %cl, %ecx, %eax 587; X32-SSE2-NEXT: retl 588; 589; X64-AVX2-LABEL: fshr_i32_undef2: 590; X64-AVX2: # %bb.0: 591; X64-AVX2-NEXT: movl %esi, %eax 592; X64-AVX2-NEXT: shrdl %cl, %edi, %eax 593; X64-AVX2-NEXT: retq 594 %res = call i32 @llvm.fshr.i32(i32 %a0, i32 %a1, i32 undef) 595 ret i32 %res 596} 597 598; shift zero args 599 600define i32 @fshl_i32_zero0(i32 %a0, i32 %a1) nounwind { 601; X32-SSE2-LABEL: fshl_i32_zero0: 602; X32-SSE2: # %bb.0: 603; X32-SSE2-NEXT: movb {{[0-9]+}}(%esp), %cl 604; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %edx 605; X32-SSE2-NEXT: xorl %eax, %eax 606; X32-SSE2-NEXT: shldl %cl, %edx, %eax 607; X32-SSE2-NEXT: retl 608; 609; X64-AVX2-LABEL: fshl_i32_zero0: 610; X64-AVX2: # %bb.0: 611; X64-AVX2-NEXT: movl %esi, %ecx 612; X64-AVX2-NEXT: xorl %eax, %eax 613; X64-AVX2-NEXT: # kill: def $cl killed $cl killed $ecx 614; X64-AVX2-NEXT: shldl %cl, %edi, %eax 615; X64-AVX2-NEXT: retq 616 %res = call i32 @llvm.fshl.i32(i32 0, i32 %a0, i32 %a1) 617 ret i32 %res 618} 619 620define i32 @fshl_i32_zero0_cst(i32 %a0) nounwind { 621; X32-SSE2-LABEL: fshl_i32_zero0_cst: 622; X32-SSE2: # %bb.0: 623; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax 624; X32-SSE2-NEXT: shrl $23, %eax 625; X32-SSE2-NEXT: retl 626; 627; X64-AVX2-LABEL: fshl_i32_zero0_cst: 628; X64-AVX2: # %bb.0: 629; X64-AVX2-NEXT: movl %edi, %eax 630; X64-AVX2-NEXT: shrl $23, %eax 631; X64-AVX2-NEXT: retq 632 %res = call i32 @llvm.fshl.i32(i32 0, i32 %a0, i32 9) 633 ret i32 %res 634} 635 636define i32 @fshl_i32_zero1(i32 %a0, i32 %a1) nounwind { 637; X32-SSE2-LABEL: fshl_i32_zero1: 638; X32-SSE2: # %bb.0: 639; X32-SSE2-NEXT: movb {{[0-9]+}}(%esp), %cl 640; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax 641; X32-SSE2-NEXT: xorl %edx, %edx 642; X32-SSE2-NEXT: shldl %cl, %edx, %eax 643; X32-SSE2-NEXT: retl 644; 645; X64-AVX2-LABEL: fshl_i32_zero1: 646; X64-AVX2: # %bb.0: 647; X64-AVX2-NEXT: movl %esi, %ecx 648; X64-AVX2-NEXT: movl %edi, %eax 649; X64-AVX2-NEXT: xorl %edx, %edx 650; X64-AVX2-NEXT: # kill: def $cl killed $cl killed $ecx 651; X64-AVX2-NEXT: shldl %cl, %edx, %eax 652; X64-AVX2-NEXT: retq 653 %res = call i32 @llvm.fshl.i32(i32 %a0, i32 0, i32 %a1) 654 ret i32 %res 655} 656 657define i32 @fshl_i32_zero1_cst(i32 %a0) nounwind { 658; X32-SSE2-LABEL: fshl_i32_zero1_cst: 659; X32-SSE2: # %bb.0: 660; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax 661; X32-SSE2-NEXT: shll $9, %eax 662; X32-SSE2-NEXT: retl 663; 664; X64-AVX2-LABEL: fshl_i32_zero1_cst: 665; X64-AVX2: # %bb.0: 666; X64-AVX2-NEXT: movl %edi, %eax 667; X64-AVX2-NEXT: shll $9, %eax 668; X64-AVX2-NEXT: retq 669 %res = call i32 @llvm.fshl.i32(i32 %a0, i32 0, i32 9) 670 ret i32 %res 671} 672 673define i32 @fshr_i32_zero0(i32 %a0, i32 %a1) nounwind { 674; X32-SSE2-LABEL: fshr_i32_zero0: 675; X32-SSE2: # %bb.0: 676; X32-SSE2-NEXT: movb {{[0-9]+}}(%esp), %cl 677; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax 678; X32-SSE2-NEXT: xorl %edx, %edx 679; X32-SSE2-NEXT: shrdl %cl, %edx, %eax 680; X32-SSE2-NEXT: retl 681; 682; X64-AVX2-LABEL: fshr_i32_zero0: 683; X64-AVX2: # %bb.0: 684; X64-AVX2-NEXT: movl %esi, %ecx 685; X64-AVX2-NEXT: movl %edi, %eax 686; X64-AVX2-NEXT: xorl %edx, %edx 687; X64-AVX2-NEXT: # kill: def $cl killed $cl killed $ecx 688; X64-AVX2-NEXT: shrdl %cl, %edx, %eax 689; X64-AVX2-NEXT: retq 690 %res = call i32 @llvm.fshr.i32(i32 0, i32 %a0, i32 %a1) 691 ret i32 %res 692} 693 694define i32 @fshr_i32_zero0_cst(i32 %a0) nounwind { 695; X32-SSE2-LABEL: fshr_i32_zero0_cst: 696; X32-SSE2: # %bb.0: 697; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax 698; X32-SSE2-NEXT: shrl $9, %eax 699; X32-SSE2-NEXT: retl 700; 701; X64-AVX2-LABEL: fshr_i32_zero0_cst: 702; X64-AVX2: # %bb.0: 703; X64-AVX2-NEXT: movl %edi, %eax 704; X64-AVX2-NEXT: shrl $9, %eax 705; X64-AVX2-NEXT: retq 706 %res = call i32 @llvm.fshr.i32(i32 0, i32 %a0, i32 9) 707 ret i32 %res 708} 709 710define i32 @fshr_i32_zero1(i32 %a0, i32 %a1) nounwind { 711; X32-SSE2-LABEL: fshr_i32_zero1: 712; X32-SSE2: # %bb.0: 713; X32-SSE2-NEXT: movb {{[0-9]+}}(%esp), %cl 714; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %edx 715; X32-SSE2-NEXT: xorl %eax, %eax 716; X32-SSE2-NEXT: shrdl %cl, %edx, %eax 717; X32-SSE2-NEXT: retl 718; 719; X64-AVX2-LABEL: fshr_i32_zero1: 720; X64-AVX2: # %bb.0: 721; X64-AVX2-NEXT: movl %esi, %ecx 722; X64-AVX2-NEXT: xorl %eax, %eax 723; X64-AVX2-NEXT: # kill: def $cl killed $cl killed $ecx 724; X64-AVX2-NEXT: shrdl %cl, %edi, %eax 725; X64-AVX2-NEXT: retq 726 %res = call i32 @llvm.fshr.i32(i32 %a0, i32 0, i32 %a1) 727 ret i32 %res 728} 729 730define i32 @fshr_i32_zero1_cst(i32 %a0) nounwind { 731; X32-SSE2-LABEL: fshr_i32_zero1_cst: 732; X32-SSE2: # %bb.0: 733; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax 734; X32-SSE2-NEXT: shll $23, %eax 735; X32-SSE2-NEXT: retl 736; 737; X64-AVX2-LABEL: fshr_i32_zero1_cst: 738; X64-AVX2: # %bb.0: 739; X64-AVX2-NEXT: movl %edi, %eax 740; X64-AVX2-NEXT: shll $23, %eax 741; X64-AVX2-NEXT: retq 742 %res = call i32 @llvm.fshr.i32(i32 %a0, i32 0, i32 9) 743 ret i32 %res 744} 745 746; shift by zero 747 748define i32 @fshl_i32_zero2(i32 %a0, i32 %a1) nounwind { 749; X32-SSE2-LABEL: fshl_i32_zero2: 750; X32-SSE2: # %bb.0: 751; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax 752; X32-SSE2-NEXT: retl 753; 754; X64-AVX2-LABEL: fshl_i32_zero2: 755; X64-AVX2: # %bb.0: 756; X64-AVX2-NEXT: movl %edi, %eax 757; X64-AVX2-NEXT: retq 758 %res = call i32 @llvm.fshl.i32(i32 %a0, i32 %a1, i32 0) 759 ret i32 %res 760} 761 762define i32 @fshr_i32_zero2(i32 %a0, i32 %a1) nounwind { 763; X32-SSE2-LABEL: fshr_i32_zero2: 764; X32-SSE2: # %bb.0: 765; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax 766; X32-SSE2-NEXT: retl 767; 768; X64-AVX2-LABEL: fshr_i32_zero2: 769; X64-AVX2: # %bb.0: 770; X64-AVX2-NEXT: movl %esi, %eax 771; X64-AVX2-NEXT: retq 772 %res = call i32 @llvm.fshr.i32(i32 %a0, i32 %a1, i32 0) 773 ret i32 %res 774} 775 776; With constant shift amount, this is 'shrd' or 'shld'. 777 778define i32 @fshr_i32_const_shift(i32 %x, i32 %y) nounwind { 779; X32-SSE2-LABEL: fshr_i32_const_shift: 780; X32-SSE2: # %bb.0: 781; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %ecx 782; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax 783; X32-SSE2-NEXT: shrdl $9, %ecx, %eax 784; X32-SSE2-NEXT: retl 785; 786; X64-AVX2-LABEL: fshr_i32_const_shift: 787; X64-AVX2: # %bb.0: 788; X64-AVX2-NEXT: movl %edi, %eax 789; X64-AVX2-NEXT: shldl $23, %esi, %eax 790; X64-AVX2-NEXT: retq 791 %f = call i32 @llvm.fshr.i32(i32 %x, i32 %y, i32 9) 792 ret i32 %f 793} 794 795; Check modulo math on shift amount. 41-32=9, but right-shift may became left, so 32-9=23. 796 797define i32 @fshr_i32_const_overshift(i32 %x, i32 %y) nounwind { 798; X32-SSE2-LABEL: fshr_i32_const_overshift: 799; X32-SSE2: # %bb.0: 800; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %ecx 801; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax 802; X32-SSE2-NEXT: shrdl $9, %ecx, %eax 803; X32-SSE2-NEXT: retl 804; 805; X64-AVX2-LABEL: fshr_i32_const_overshift: 806; X64-AVX2: # %bb.0: 807; X64-AVX2-NEXT: movl %edi, %eax 808; X64-AVX2-NEXT: shldl $23, %esi, %eax 809; X64-AVX2-NEXT: retq 810 %f = call i32 @llvm.fshr.i32(i32 %x, i32 %y, i32 41) 811 ret i32 %f 812} 813 814; 64-bit should also work. 105-64 = 41, but right-shift became left, so 64-41=23. 815 816define i64 @fshr_i64_const_overshift(i64 %x, i64 %y) nounwind { 817; X32-SSE2-LABEL: fshr_i64_const_overshift: 818; X32-SSE2: # %bb.0: 819; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax 820; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %ecx 821; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %edx 822; X32-SSE2-NEXT: shrdl $9, %ecx, %eax 823; X32-SSE2-NEXT: shldl $23, %ecx, %edx 824; X32-SSE2-NEXT: retl 825; 826; X64-AVX2-LABEL: fshr_i64_const_overshift: 827; X64-AVX2: # %bb.0: 828; X64-AVX2-NEXT: movq %rdi, %rax 829; X64-AVX2-NEXT: shldq $23, %rsi, %rax 830; X64-AVX2-NEXT: retq 831 %f = call i64 @llvm.fshr.i64(i64 %x, i64 %y, i64 105) 832 ret i64 %f 833} 834 835; This should work without any node-specific logic. 836 837define i8 @fshr_i8_const_fold() nounwind { 838; ANY-LABEL: fshr_i8_const_fold: 839; ANY: # %bb.0: 840; ANY-NEXT: movb $-2, %al 841; ANY-NEXT: ret{{[l|q]}} 842 %f = call i8 @llvm.fshr.i8(i8 255, i8 0, i8 7) 843 ret i8 %f 844} 845 846define i32 @fshl_i32_shift_by_bitwidth(i32 %x, i32 %y) nounwind { 847; X32-SSE2-LABEL: fshl_i32_shift_by_bitwidth: 848; X32-SSE2: # %bb.0: 849; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax 850; X32-SSE2-NEXT: retl 851; 852; X64-AVX2-LABEL: fshl_i32_shift_by_bitwidth: 853; X64-AVX2: # %bb.0: 854; X64-AVX2-NEXT: movl %edi, %eax 855; X64-AVX2-NEXT: retq 856 %f = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 32) 857 ret i32 %f 858} 859 860define i32 @fshr_i32_shift_by_bitwidth(i32 %x, i32 %y) nounwind { 861; X32-SSE2-LABEL: fshr_i32_shift_by_bitwidth: 862; X32-SSE2: # %bb.0: 863; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax 864; X32-SSE2-NEXT: retl 865; 866; X64-AVX2-LABEL: fshr_i32_shift_by_bitwidth: 867; X64-AVX2: # %bb.0: 868; X64-AVX2-NEXT: movl %esi, %eax 869; X64-AVX2-NEXT: retq 870 %f = call i32 @llvm.fshr.i32(i32 %x, i32 %y, i32 32) 871 ret i32 %f 872} 873 874define <4 x i32> @fshl_v4i32_shift_by_bitwidth(<4 x i32> %x, <4 x i32> %y) nounwind { 875; ANY-LABEL: fshl_v4i32_shift_by_bitwidth: 876; ANY: # %bb.0: 877; ANY-NEXT: ret{{[l|q]}} 878 %f = call <4 x i32> @llvm.fshl.v4i32(<4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 32, i32 32, i32 32, i32 32>) 879 ret <4 x i32> %f 880} 881 882define <4 x i32> @fshr_v4i32_shift_by_bitwidth(<4 x i32> %x, <4 x i32> %y) nounwind { 883; X32-SSE2-LABEL: fshr_v4i32_shift_by_bitwidth: 884; X32-SSE2: # %bb.0: 885; X32-SSE2-NEXT: movaps %xmm1, %xmm0 886; X32-SSE2-NEXT: retl 887; 888; X64-AVX2-LABEL: fshr_v4i32_shift_by_bitwidth: 889; X64-AVX2: # %bb.0: 890; X64-AVX2-NEXT: vmovaps %xmm1, %xmm0 891; X64-AVX2-NEXT: retq 892 %f = call <4 x i32> @llvm.fshr.v4i32(<4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 32, i32 32, i32 32, i32 32>) 893 ret <4 x i32> %f 894} 895 896%struct.S = type { [11 x i8], i8 } 897define void @PR45265(i32 %0, %struct.S* nocapture readonly %1) nounwind { 898; X32-SSE2-LABEL: PR45265: 899; X32-SSE2: # %bb.0: 900; X32-SSE2-NEXT: pushl %ebx 901; X32-SSE2-NEXT: pushl %edi 902; X32-SSE2-NEXT: pushl %esi 903; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax 904; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %ecx 905; X32-SSE2-NEXT: leal (%eax,%eax,2), %edx 906; X32-SSE2-NEXT: movzwl 8(%ecx,%edx,4), %esi 907; X32-SSE2-NEXT: movsbl 10(%ecx,%edx,4), %edi 908; X32-SSE2-NEXT: movl %edi, %ebx 909; X32-SSE2-NEXT: shll $16, %ebx 910; X32-SSE2-NEXT: orl %esi, %ebx 911; X32-SSE2-NEXT: movl 4(%ecx,%edx,4), %ecx 912; X32-SSE2-NEXT: shrdl $8, %ebx, %ecx 913; X32-SSE2-NEXT: xorl %eax, %ecx 914; X32-SSE2-NEXT: sarl $31, %eax 915; X32-SSE2-NEXT: sarl $31, %edi 916; X32-SSE2-NEXT: shldl $24, %ebx, %edi 917; X32-SSE2-NEXT: xorl %eax, %edi 918; X32-SSE2-NEXT: orl %edi, %ecx 919; X32-SSE2-NEXT: jne .LBB44_1 920; X32-SSE2-NEXT: # %bb.2: 921; X32-SSE2-NEXT: popl %esi 922; X32-SSE2-NEXT: popl %edi 923; X32-SSE2-NEXT: popl %ebx 924; X32-SSE2-NEXT: jmp _Z3foov # TAILCALL 925; X32-SSE2-NEXT: .LBB44_1: 926; X32-SSE2-NEXT: popl %esi 927; X32-SSE2-NEXT: popl %edi 928; X32-SSE2-NEXT: popl %ebx 929; X32-SSE2-NEXT: retl 930; 931; X64-AVX2-LABEL: PR45265: 932; X64-AVX2: # %bb.0: 933; X64-AVX2-NEXT: movslq %edi, %rax 934; X64-AVX2-NEXT: leaq (%rax,%rax,2), %rcx 935; X64-AVX2-NEXT: movsbq 10(%rsi,%rcx,4), %rdx 936; X64-AVX2-NEXT: shlq $16, %rdx 937; X64-AVX2-NEXT: movzwl 8(%rsi,%rcx,4), %edi 938; X64-AVX2-NEXT: orq %rdx, %rdi 939; X64-AVX2-NEXT: movq (%rsi,%rcx,4), %rcx 940; X64-AVX2-NEXT: shrdq $40, %rdi, %rcx 941; X64-AVX2-NEXT: cmpq %rax, %rcx 942; X64-AVX2-NEXT: jne .LBB44_1 943; X64-AVX2-NEXT: # %bb.2: 944; X64-AVX2-NEXT: jmp _Z3foov # TAILCALL 945; X64-AVX2-NEXT: .LBB44_1: 946; X64-AVX2-NEXT: retq 947 %3 = sext i32 %0 to i64 948 %4 = getelementptr inbounds %struct.S, %struct.S* %1, i64 %3 949 %5 = bitcast %struct.S* %4 to i88* 950 %6 = load i88, i88* %5, align 1 951 %7 = ashr i88 %6, 40 952 %8 = trunc i88 %7 to i64 953 %9 = icmp eq i64 %8, %3 954 br i1 %9, label %10, label %11 955 95610: 957 tail call void @_Z3foov() 958 br label %11 959 96011: 961 ret void 962} 963declare dso_local void @_Z3foov() 964