1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=i686-linux -show-mc-encoding | FileCheck %s --check-prefix=CHECK32 3; RUN: llc < %s -mtriple=x86_64-linux -show-mc-encoding | FileCheck %s --check-prefix=CHECK64 4; RUN: llc < %s -mtriple=x86_64-win32 -show-mc-encoding | FileCheck %s --check-prefix=WIN64 5 6declare dso_local void @foo() 7declare dso_local void @bar() 8 9define void @f(i32 %x, i32 %y) optsize { 10; CHECK32-LABEL: f: 11; CHECK32: # %bb.0: # %entry 12; CHECK32-NEXT: movl {{[0-9]+}}(%esp), %eax # encoding: [0x8b,0x44,0x24,0x04] 13; CHECK32-NEXT: cmpl {{[0-9]+}}(%esp), %eax # encoding: [0x3b,0x44,0x24,0x08] 14; CHECK32-NEXT: jne bar # TAILCALL 15; CHECK32-NEXT: # encoding: [0x75,A] 16; CHECK32-NEXT: # fixup A - offset: 1, value: bar-1, kind: FK_PCRel_1 17; CHECK32-NEXT: # %bb.1: # %bb1 18; CHECK32-NEXT: jmp foo # TAILCALL 19; CHECK32-NEXT: # encoding: [0xeb,A] 20; CHECK32-NEXT: # fixup A - offset: 1, value: foo-1, kind: FK_PCRel_1 21; 22; CHECK64-LABEL: f: 23; CHECK64: # %bb.0: # %entry 24; CHECK64-NEXT: cmpl %esi, %edi # encoding: [0x39,0xf7] 25; CHECK64-NEXT: jne bar # TAILCALL 26; CHECK64-NEXT: # encoding: [0x75,A] 27; CHECK64-NEXT: # fixup A - offset: 1, value: bar-1, kind: FK_PCRel_1 28; CHECK64-NEXT: # %bb.1: # %bb1 29; CHECK64-NEXT: jmp foo # TAILCALL 30; CHECK64-NEXT: # encoding: [0xeb,A] 31; CHECK64-NEXT: # fixup A - offset: 1, value: foo-1, kind: FK_PCRel_1 32; 33; WIN64-LABEL: f: 34; WIN64: # %bb.0: # %entry 35; WIN64-NEXT: cmpl %edx, %ecx # encoding: [0x39,0xd1] 36; WIN64-NEXT: jne bar # TAILCALL 37; WIN64-NEXT: # encoding: [0x75,A] 38; WIN64-NEXT: # fixup A - offset: 1, value: bar-1, kind: FK_PCRel_1 39; WIN64-NEXT: # %bb.1: # %bb1 40; WIN64-NEXT: jmp foo # TAILCALL 41; WIN64-NEXT: # encoding: [0xeb,A] 42; WIN64-NEXT: # fixup A - offset: 1, value: foo-1, kind: FK_PCRel_1 43entry: 44 %p = icmp eq i32 %x, %y 45 br i1 %p, label %bb1, label %bb2 46bb1: 47 tail call void @foo() 48 ret void 49bb2: 50 tail call void @bar() 51 ret void 52 53; Check that the asm doesn't just look good, but uses the correct encoding. 54} 55 56define void @f_non_leaf(i32 %x, i32 %y) optsize { 57; CHECK32-LABEL: f_non_leaf: 58; CHECK32: # %bb.0: # %entry 59; CHECK32-NEXT: pushl %ebx # encoding: [0x53] 60; CHECK32-NEXT: .cfi_def_cfa_offset 8 61; CHECK32-NEXT: .cfi_offset %ebx, -8 62; CHECK32-NEXT: movl {{[0-9]+}}(%esp), %eax # encoding: [0x8b,0x44,0x24,0x08] 63; CHECK32-NEXT: #APP 64; CHECK32-NEXT: #NO_APP 65; CHECK32-NEXT: cmpl {{[0-9]+}}(%esp), %eax # encoding: [0x3b,0x44,0x24,0x0c] 66; CHECK32-NEXT: jne .LBB1_2 # encoding: [0x75,A] 67; CHECK32-NEXT: # fixup A - offset: 1, value: .LBB1_2-1, kind: FK_PCRel_1 68; CHECK32-NEXT: # %bb.1: # %bb1 69; CHECK32-NEXT: popl %ebx # encoding: [0x5b] 70; CHECK32-NEXT: .cfi_def_cfa_offset 4 71; CHECK32-NEXT: jmp foo # TAILCALL 72; CHECK32-NEXT: # encoding: [0xeb,A] 73; CHECK32-NEXT: # fixup A - offset: 1, value: foo-1, kind: FK_PCRel_1 74; CHECK32-NEXT: .LBB1_2: # %bb2 75; CHECK32-NEXT: .cfi_def_cfa_offset 8 76; CHECK32-NEXT: popl %ebx # encoding: [0x5b] 77; CHECK32-NEXT: .cfi_def_cfa_offset 4 78; CHECK32-NEXT: jmp bar # TAILCALL 79; CHECK32-NEXT: # encoding: [0xeb,A] 80; CHECK32-NEXT: # fixup A - offset: 1, value: bar-1, kind: FK_PCRel_1 81; 82; CHECK64-LABEL: f_non_leaf: 83; CHECK64: # %bb.0: # %entry 84; CHECK64-NEXT: pushq %rbx # encoding: [0x53] 85; CHECK64-NEXT: .cfi_def_cfa_offset 16 86; CHECK64-NEXT: .cfi_offset %rbx, -16 87; CHECK64-NEXT: #APP 88; CHECK64-NEXT: #NO_APP 89; CHECK64-NEXT: cmpl %esi, %edi # encoding: [0x39,0xf7] 90; CHECK64-NEXT: jne .LBB1_2 # encoding: [0x75,A] 91; CHECK64-NEXT: # fixup A - offset: 1, value: .LBB1_2-1, kind: FK_PCRel_1 92; CHECK64-NEXT: # %bb.1: # %bb1 93; CHECK64-NEXT: popq %rbx # encoding: [0x5b] 94; CHECK64-NEXT: .cfi_def_cfa_offset 8 95; CHECK64-NEXT: jmp foo # TAILCALL 96; CHECK64-NEXT: # encoding: [0xeb,A] 97; CHECK64-NEXT: # fixup A - offset: 1, value: foo-1, kind: FK_PCRel_1 98; CHECK64-NEXT: .LBB1_2: # %bb2 99; CHECK64-NEXT: .cfi_def_cfa_offset 16 100; CHECK64-NEXT: popq %rbx # encoding: [0x5b] 101; CHECK64-NEXT: .cfi_def_cfa_offset 8 102; CHECK64-NEXT: jmp bar # TAILCALL 103; CHECK64-NEXT: # encoding: [0xeb,A] 104; CHECK64-NEXT: # fixup A - offset: 1, value: bar-1, kind: FK_PCRel_1 105; 106; WIN64-LABEL: f_non_leaf: 107; WIN64: # %bb.0: # %entry 108; WIN64-NEXT: pushq %rbx # encoding: [0x53] 109; WIN64-NEXT: .seh_pushreg %rbx 110; WIN64-NEXT: .seh_endprologue 111; WIN64-NEXT: #APP 112; WIN64-NEXT: #NO_APP 113; WIN64-NEXT: cmpl %edx, %ecx # encoding: [0x39,0xd1] 114; WIN64-NEXT: jne .LBB1_2 # encoding: [0x75,A] 115; WIN64-NEXT: # fixup A - offset: 1, value: .LBB1_2-1, kind: FK_PCRel_1 116; WIN64-NEXT: # %bb.1: # %bb1 117; WIN64-NEXT: popq %rbx # encoding: [0x5b] 118; WIN64-NEXT: jmp foo # TAILCALL 119; WIN64-NEXT: # encoding: [0xeb,A] 120; WIN64-NEXT: # fixup A - offset: 1, value: foo-1, kind: FK_PCRel_1 121; WIN64-NEXT: .LBB1_2: # %bb2 122; WIN64-NEXT: nop # encoding: [0x90] 123; WIN64-NEXT: popq %rbx # encoding: [0x5b] 124; WIN64-NEXT: jmp bar # TAILCALL 125; WIN64-NEXT: # encoding: [0xeb,A] 126; WIN64-NEXT: # fixup A - offset: 1, value: bar-1, kind: FK_PCRel_1 127; WIN64-NEXT: .seh_endproc 128entry: 129 ; Force %ebx to be spilled on the stack, turning this into 130 ; not a "leaf" function for Win64. 131 tail call void asm sideeffect "", "~{ebx}"() 132 133 %p = icmp eq i32 %x, %y 134 br i1 %p, label %bb1, label %bb2 135bb1: 136 tail call void @foo() 137 ret void 138bb2: 139 tail call void @bar() 140 ret void 141 142} 143 144declare dso_local x86_thiscallcc zeroext i1 @baz(i8*, i32) 145define x86_thiscallcc zeroext i1 @BlockPlacementTest(i8* %this, i32 %x) optsize { 146; CHECK32-LABEL: BlockPlacementTest: 147; CHECK32: # %bb.0: # %entry 148; CHECK32-NEXT: movl {{[0-9]+}}(%esp), %edx # encoding: [0x8b,0x54,0x24,0x04] 149; CHECK32-NEXT: testb $42, %dl # encoding: [0xf6,0xc2,0x2a] 150; CHECK32-NEXT: je .LBB2_3 # encoding: [0x74,A] 151; CHECK32-NEXT: # fixup A - offset: 1, value: .LBB2_3-1, kind: FK_PCRel_1 152; CHECK32-NEXT: # %bb.1: # %land.rhs 153; CHECK32-NEXT: movb $1, %al # encoding: [0xb0,0x01] 154; CHECK32-NEXT: testb $44, %dl # encoding: [0xf6,0xc2,0x2c] 155; CHECK32-NEXT: je baz # TAILCALL 156; CHECK32-NEXT: # encoding: [0x74,A] 157; CHECK32-NEXT: # fixup A - offset: 1, value: baz-1, kind: FK_PCRel_1 158; CHECK32-NEXT: .LBB2_2: # %land.end 159; CHECK32-NEXT: # kill: def $al killed $al killed $eax 160; CHECK32-NEXT: retl $4 # encoding: [0xc2,0x04,0x00] 161; CHECK32-NEXT: .LBB2_3: 162; CHECK32-NEXT: xorl %eax, %eax # encoding: [0x31,0xc0] 163; CHECK32-NEXT: jmp .LBB2_2 # encoding: [0xeb,A] 164; CHECK32-NEXT: # fixup A - offset: 1, value: .LBB2_2-1, kind: FK_PCRel_1 165; 166; CHECK64-LABEL: BlockPlacementTest: 167; CHECK64: # %bb.0: # %entry 168; CHECK64-NEXT: testb $42, %sil # encoding: [0x40,0xf6,0xc6,0x2a] 169; CHECK64-NEXT: je .LBB2_3 # encoding: [0x74,A] 170; CHECK64-NEXT: # fixup A - offset: 1, value: .LBB2_3-1, kind: FK_PCRel_1 171; CHECK64-NEXT: # %bb.1: # %land.rhs 172; CHECK64-NEXT: movb $1, %al # encoding: [0xb0,0x01] 173; CHECK64-NEXT: testb $44, %sil # encoding: [0x40,0xf6,0xc6,0x2c] 174; CHECK64-NEXT: je baz # TAILCALL 175; CHECK64-NEXT: # encoding: [0x74,A] 176; CHECK64-NEXT: # fixup A - offset: 1, value: baz-1, kind: FK_PCRel_1 177; CHECK64-NEXT: .LBB2_2: # %land.end 178; CHECK64-NEXT: # kill: def $al killed $al killed $eax 179; CHECK64-NEXT: retq # encoding: [0xc3] 180; CHECK64-NEXT: .LBB2_3: 181; CHECK64-NEXT: xorl %eax, %eax # encoding: [0x31,0xc0] 182; CHECK64-NEXT: jmp .LBB2_2 # encoding: [0xeb,A] 183; CHECK64-NEXT: # fixup A - offset: 1, value: .LBB2_2-1, kind: FK_PCRel_1 184; 185; WIN64-LABEL: BlockPlacementTest: 186; WIN64: # %bb.0: # %entry 187; WIN64-NEXT: testb $42, %dl # encoding: [0xf6,0xc2,0x2a] 188; WIN64-NEXT: je .LBB2_3 # encoding: [0x74,A] 189; WIN64-NEXT: # fixup A - offset: 1, value: .LBB2_3-1, kind: FK_PCRel_1 190; WIN64-NEXT: # %bb.1: # %land.rhs 191; WIN64-NEXT: movb $1, %al # encoding: [0xb0,0x01] 192; WIN64-NEXT: testb $44, %dl # encoding: [0xf6,0xc2,0x2c] 193; WIN64-NEXT: je baz # TAILCALL 194; WIN64-NEXT: # encoding: [0x74,A] 195; WIN64-NEXT: # fixup A - offset: 1, value: baz-1, kind: FK_PCRel_1 196; WIN64-NEXT: .LBB2_2: # %land.end 197; WIN64-NEXT: # kill: def $al killed $al killed $eax 198; WIN64-NEXT: retq # encoding: [0xc3] 199; WIN64-NEXT: .LBB2_3: 200; WIN64-NEXT: xorl %eax, %eax # encoding: [0x31,0xc0] 201; WIN64-NEXT: jmp .LBB2_2 # encoding: [0xeb,A] 202; WIN64-NEXT: # fixup A - offset: 1, value: .LBB2_2-1, kind: FK_PCRel_1 203entry: 204 %and = and i32 %x, 42 205 %tobool = icmp eq i32 %and, 0 206 br i1 %tobool, label %land.end, label %land.rhs 207 208land.rhs: 209 %and6 = and i32 %x, 44 210 %tobool7 = icmp eq i32 %and6, 0 211 br i1 %tobool7, label %lor.rhs, label %land.end 212 213lor.rhs: 214 %call = tail call x86_thiscallcc zeroext i1 @baz(i8* %this, i32 %x) #2 215 br label %land.end 216 217land.end: 218 %0 = phi i1 [ false, %entry ], [ true, %land.rhs ], [ %call, %lor.rhs ] 219 ret i1 %0 220 221; Make sure machine block placement isn't confused by the conditional tail call, 222; but sees that it can fall through to the next block. 223} 224 225 226 227%"class.std::basic_string" = type { %"struct.std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Alloc_hider" } 228%"struct.std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Alloc_hider" = type { i8* } 229declare dso_local zeroext i1 @_Z20isValidIntegerSuffixN9__gnu_cxx17__normal_iteratorIPKcSsEES3_(i8*, i8*) 230 231define zeroext i1 @pr31257(%"class.std::basic_string"* nocapture readonly dereferenceable(8) %s) minsize { 232; CHECK32-LABEL: pr31257: 233; CHECK32: # %bb.0: # %entry 234; CHECK32-NEXT: pushl %ebp # encoding: [0x55] 235; CHECK32-NEXT: .cfi_def_cfa_offset 8 236; CHECK32-NEXT: pushl %ebx # encoding: [0x53] 237; CHECK32-NEXT: .cfi_def_cfa_offset 12 238; CHECK32-NEXT: pushl %edi # encoding: [0x57] 239; CHECK32-NEXT: .cfi_def_cfa_offset 16 240; CHECK32-NEXT: pushl %esi # encoding: [0x56] 241; CHECK32-NEXT: .cfi_def_cfa_offset 20 242; CHECK32-NEXT: subl $12, %esp # encoding: [0x83,0xec,0x0c] 243; CHECK32-NEXT: .cfi_def_cfa_offset 32 244; CHECK32-NEXT: .cfi_offset %esi, -20 245; CHECK32-NEXT: .cfi_offset %edi, -16 246; CHECK32-NEXT: .cfi_offset %ebx, -12 247; CHECK32-NEXT: .cfi_offset %ebp, -8 248; CHECK32-NEXT: movl {{[0-9]+}}(%esp), %eax # encoding: [0x8b,0x44,0x24,0x20] 249; CHECK32-NEXT: movl (%eax), %eax # encoding: [0x8b,0x00] 250; CHECK32-NEXT: movl -24(%eax), %edx # encoding: [0x8b,0x50,0xe8] 251; CHECK32-NEXT: leal (%eax,%edx), %ebp # encoding: [0x8d,0x2c,0x10] 252; CHECK32-NEXT: xorl %ebx, %ebx # encoding: [0x31,0xdb] 253; CHECK32-NEXT: pushl $2 # encoding: [0x6a,0x02] 254; CHECK32-NEXT: .cfi_adjust_cfa_offset 4 255; CHECK32-NEXT: popl %esi # encoding: [0x5e] 256; CHECK32-NEXT: .cfi_adjust_cfa_offset -4 257; CHECK32-NEXT: xorl %edi, %edi # encoding: [0x31,0xff] 258; CHECK32-NEXT: incl %edi # encoding: [0x47] 259; CHECK32-NEXT: .LBB3_1: # %for.cond 260; CHECK32-NEXT: # =>This Inner Loop Header: Depth=1 261; CHECK32-NEXT: testl %edx, %edx # encoding: [0x85,0xd2] 262; CHECK32-NEXT: je .LBB3_13 # encoding: [0x74,A] 263; CHECK32-NEXT: # fixup A - offset: 1, value: .LBB3_13-1, kind: FK_PCRel_1 264; CHECK32-NEXT: # %bb.2: # %for.body 265; CHECK32-NEXT: # in Loop: Header=BB3_1 Depth=1 266; CHECK32-NEXT: cmpl $2, %ebx # encoding: [0x83,0xfb,0x02] 267; CHECK32-NEXT: je .LBB3_11 # encoding: [0x74,A] 268; CHECK32-NEXT: # fixup A - offset: 1, value: .LBB3_11-1, kind: FK_PCRel_1 269; CHECK32-NEXT: # %bb.3: # %for.body 270; CHECK32-NEXT: # in Loop: Header=BB3_1 Depth=1 271; CHECK32-NEXT: cmpl $1, %ebx # encoding: [0x83,0xfb,0x01] 272; CHECK32-NEXT: je .LBB3_9 # encoding: [0x74,A] 273; CHECK32-NEXT: # fixup A - offset: 1, value: .LBB3_9-1, kind: FK_PCRel_1 274; CHECK32-NEXT: # %bb.4: # %for.body 275; CHECK32-NEXT: # in Loop: Header=BB3_1 Depth=1 276; CHECK32-NEXT: testl %ebx, %ebx # encoding: [0x85,0xdb] 277; CHECK32-NEXT: jne .LBB3_10 # encoding: [0x75,A] 278; CHECK32-NEXT: # fixup A - offset: 1, value: .LBB3_10-1, kind: FK_PCRel_1 279; CHECK32-NEXT: # %bb.5: # %sw.bb 280; CHECK32-NEXT: # in Loop: Header=BB3_1 Depth=1 281; CHECK32-NEXT: movzbl (%eax), %ecx # encoding: [0x0f,0xb6,0x08] 282; CHECK32-NEXT: cmpl $43, %ecx # encoding: [0x83,0xf9,0x2b] 283; CHECK32-NEXT: movl %edi, %ebx # encoding: [0x89,0xfb] 284; CHECK32-NEXT: je .LBB3_10 # encoding: [0x74,A] 285; CHECK32-NEXT: # fixup A - offset: 1, value: .LBB3_10-1, kind: FK_PCRel_1 286; CHECK32-NEXT: # %bb.6: # %sw.bb 287; CHECK32-NEXT: # in Loop: Header=BB3_1 Depth=1 288; CHECK32-NEXT: cmpb $45, %cl # encoding: [0x80,0xf9,0x2d] 289; CHECK32-NEXT: movl %edi, %ebx # encoding: [0x89,0xfb] 290; CHECK32-NEXT: je .LBB3_10 # encoding: [0x74,A] 291; CHECK32-NEXT: # fixup A - offset: 1, value: .LBB3_10-1, kind: FK_PCRel_1 292; CHECK32-NEXT: jmp .LBB3_7 # encoding: [0xeb,A] 293; CHECK32-NEXT: # fixup A - offset: 1, value: .LBB3_7-1, kind: FK_PCRel_1 294; CHECK32-NEXT: .LBB3_11: # %sw.bb22 295; CHECK32-NEXT: # in Loop: Header=BB3_1 Depth=1 296; CHECK32-NEXT: movzbl (%eax), %ecx # encoding: [0x0f,0xb6,0x08] 297; CHECK32-NEXT: addl $-48, %ecx # encoding: [0x83,0xc1,0xd0] 298; CHECK32-NEXT: cmpl $10, %ecx # encoding: [0x83,0xf9,0x0a] 299; CHECK32-NEXT: movl %esi, %ebx # encoding: [0x89,0xf3] 300; CHECK32-NEXT: jb .LBB3_10 # encoding: [0x72,A] 301; CHECK32-NEXT: # fixup A - offset: 1, value: .LBB3_10-1, kind: FK_PCRel_1 302; CHECK32-NEXT: jmp .LBB3_12 # encoding: [0xeb,A] 303; CHECK32-NEXT: # fixup A - offset: 1, value: .LBB3_12-1, kind: FK_PCRel_1 304; CHECK32-NEXT: .LBB3_9: # %sw.bb14 305; CHECK32-NEXT: # in Loop: Header=BB3_1 Depth=1 306; CHECK32-NEXT: movzbl (%eax), %ecx # encoding: [0x0f,0xb6,0x08] 307; CHECK32-NEXT: .LBB3_7: # %if.else 308; CHECK32-NEXT: # in Loop: Header=BB3_1 Depth=1 309; CHECK32-NEXT: addl $-48, %ecx # encoding: [0x83,0xc1,0xd0] 310; CHECK32-NEXT: cmpl $10, %ecx # encoding: [0x83,0xf9,0x0a] 311; CHECK32-NEXT: movl %esi, %ebx # encoding: [0x89,0xf3] 312; CHECK32-NEXT: jae .LBB3_8 # encoding: [0x73,A] 313; CHECK32-NEXT: # fixup A - offset: 1, value: .LBB3_8-1, kind: FK_PCRel_1 314; CHECK32-NEXT: .LBB3_10: # %for.inc 315; CHECK32-NEXT: # in Loop: Header=BB3_1 Depth=1 316; CHECK32-NEXT: incl %eax # encoding: [0x40] 317; CHECK32-NEXT: decl %edx # encoding: [0x4a] 318; CHECK32-NEXT: jmp .LBB3_1 # encoding: [0xeb,A] 319; CHECK32-NEXT: # fixup A - offset: 1, value: .LBB3_1-1, kind: FK_PCRel_1 320; CHECK32-NEXT: .LBB3_13: 321; CHECK32-NEXT: cmpl $2, %ebx # encoding: [0x83,0xfb,0x02] 322; CHECK32-NEXT: sete %al # encoding: [0x0f,0x94,0xc0] 323; CHECK32-NEXT: jmp .LBB3_14 # encoding: [0xeb,A] 324; CHECK32-NEXT: # fixup A - offset: 1, value: .LBB3_14-1, kind: FK_PCRel_1 325; CHECK32-NEXT: .LBB3_8: 326; CHECK32-NEXT: xorl %eax, %eax # encoding: [0x31,0xc0] 327; CHECK32-NEXT: .LBB3_14: # %cleanup.thread 328; CHECK32-NEXT: # kill: def $al killed $al killed $eax 329; CHECK32-NEXT: addl $12, %esp # encoding: [0x83,0xc4,0x0c] 330; CHECK32-NEXT: .cfi_def_cfa_offset 20 331; CHECK32-NEXT: .LBB3_15: # %cleanup.thread 332; CHECK32-NEXT: popl %esi # encoding: [0x5e] 333; CHECK32-NEXT: .cfi_def_cfa_offset 16 334; CHECK32-NEXT: popl %edi # encoding: [0x5f] 335; CHECK32-NEXT: .cfi_def_cfa_offset 12 336; CHECK32-NEXT: popl %ebx # encoding: [0x5b] 337; CHECK32-NEXT: .cfi_def_cfa_offset 8 338; CHECK32-NEXT: popl %ebp # encoding: [0x5d] 339; CHECK32-NEXT: .cfi_def_cfa_offset 4 340; CHECK32-NEXT: retl # encoding: [0xc3] 341; CHECK32-NEXT: .LBB3_12: # %if.else28 342; CHECK32-NEXT: .cfi_def_cfa_offset 32 343; CHECK32-NEXT: subl $8, %esp # encoding: [0x83,0xec,0x08] 344; CHECK32-NEXT: .cfi_adjust_cfa_offset 8 345; CHECK32-NEXT: pushl %ebp # encoding: [0x55] 346; CHECK32-NEXT: .cfi_adjust_cfa_offset 4 347; CHECK32-NEXT: pushl %eax # encoding: [0x50] 348; CHECK32-NEXT: .cfi_adjust_cfa_offset 4 349; CHECK32-NEXT: calll _Z20isValidIntegerSuffixN9__gnu_cxx17__normal_iteratorIPKcSsEES3_ # encoding: [0xe8,A,A,A,A] 350; CHECK32-NEXT: # fixup A - offset: 1, value: _Z20isValidIntegerSuffixN9__gnu_cxx17__normal_iteratorIPKcSsEES3_-4, kind: FK_PCRel_4 351; CHECK32-NEXT: addl $28, %esp # encoding: [0x83,0xc4,0x1c] 352; CHECK32-NEXT: .cfi_adjust_cfa_offset -28 353; CHECK32-NEXT: jmp .LBB3_15 # encoding: [0xeb,A] 354; CHECK32-NEXT: # fixup A - offset: 1, value: .LBB3_15-1, kind: FK_PCRel_1 355; 356; CHECK64-LABEL: pr31257: 357; CHECK64: # %bb.0: # %entry 358; CHECK64-NEXT: movq (%rdi), %rdi # encoding: [0x48,0x8b,0x3f] 359; CHECK64-NEXT: movq -24(%rdi), %rax # encoding: [0x48,0x8b,0x47,0xe8] 360; CHECK64-NEXT: leaq (%rdi,%rax), %rsi # encoding: [0x48,0x8d,0x34,0x07] 361; CHECK64-NEXT: xorl %ecx, %ecx # encoding: [0x31,0xc9] 362; CHECK64-NEXT: pushq $2 # encoding: [0x6a,0x02] 363; CHECK64-NEXT: .cfi_adjust_cfa_offset 8 364; CHECK64-NEXT: popq %r9 # encoding: [0x41,0x59] 365; CHECK64-NEXT: .cfi_adjust_cfa_offset -8 366; CHECK64-NEXT: pushq $1 # encoding: [0x6a,0x01] 367; CHECK64-NEXT: .cfi_adjust_cfa_offset 8 368; CHECK64-NEXT: popq %r8 # encoding: [0x41,0x58] 369; CHECK64-NEXT: .cfi_adjust_cfa_offset -8 370; CHECK64-NEXT: .LBB3_1: # %for.cond 371; CHECK64-NEXT: # =>This Inner Loop Header: Depth=1 372; CHECK64-NEXT: testq %rax, %rax # encoding: [0x48,0x85,0xc0] 373; CHECK64-NEXT: je .LBB3_12 # encoding: [0x74,A] 374; CHECK64-NEXT: # fixup A - offset: 1, value: .LBB3_12-1, kind: FK_PCRel_1 375; CHECK64-NEXT: # %bb.2: # %for.body 376; CHECK64-NEXT: # in Loop: Header=BB3_1 Depth=1 377; CHECK64-NEXT: cmpl $2, %ecx # encoding: [0x83,0xf9,0x02] 378; CHECK64-NEXT: je .LBB3_10 # encoding: [0x74,A] 379; CHECK64-NEXT: # fixup A - offset: 1, value: .LBB3_10-1, kind: FK_PCRel_1 380; CHECK64-NEXT: # %bb.3: # %for.body 381; CHECK64-NEXT: # in Loop: Header=BB3_1 Depth=1 382; CHECK64-NEXT: cmpl $1, %ecx # encoding: [0x83,0xf9,0x01] 383; CHECK64-NEXT: je .LBB3_8 # encoding: [0x74,A] 384; CHECK64-NEXT: # fixup A - offset: 1, value: .LBB3_8-1, kind: FK_PCRel_1 385; CHECK64-NEXT: # %bb.4: # %for.body 386; CHECK64-NEXT: # in Loop: Header=BB3_1 Depth=1 387; CHECK64-NEXT: testl %ecx, %ecx # encoding: [0x85,0xc9] 388; CHECK64-NEXT: jne .LBB3_11 # encoding: [0x75,A] 389; CHECK64-NEXT: # fixup A - offset: 1, value: .LBB3_11-1, kind: FK_PCRel_1 390; CHECK64-NEXT: # %bb.5: # %sw.bb 391; CHECK64-NEXT: # in Loop: Header=BB3_1 Depth=1 392; CHECK64-NEXT: movzbl (%rdi), %edx # encoding: [0x0f,0xb6,0x17] 393; CHECK64-NEXT: cmpl $43, %edx # encoding: [0x83,0xfa,0x2b] 394; CHECK64-NEXT: movl %r8d, %ecx # encoding: [0x44,0x89,0xc1] 395; CHECK64-NEXT: je .LBB3_11 # encoding: [0x74,A] 396; CHECK64-NEXT: # fixup A - offset: 1, value: .LBB3_11-1, kind: FK_PCRel_1 397; CHECK64-NEXT: # %bb.6: # %sw.bb 398; CHECK64-NEXT: # in Loop: Header=BB3_1 Depth=1 399; CHECK64-NEXT: cmpb $45, %dl # encoding: [0x80,0xfa,0x2d] 400; CHECK64-NEXT: movl %r8d, %ecx # encoding: [0x44,0x89,0xc1] 401; CHECK64-NEXT: je .LBB3_11 # encoding: [0x74,A] 402; CHECK64-NEXT: # fixup A - offset: 1, value: .LBB3_11-1, kind: FK_PCRel_1 403; CHECK64-NEXT: # %bb.7: # %if.else 404; CHECK64-NEXT: # in Loop: Header=BB3_1 Depth=1 405; CHECK64-NEXT: addl $-48, %edx # encoding: [0x83,0xc2,0xd0] 406; CHECK64-NEXT: cmpl $10, %edx # encoding: [0x83,0xfa,0x0a] 407; CHECK64-NEXT: jmp .LBB3_9 # encoding: [0xeb,A] 408; CHECK64-NEXT: # fixup A - offset: 1, value: .LBB3_9-1, kind: FK_PCRel_1 409; CHECK64-NEXT: .LBB3_8: # %sw.bb14 410; CHECK64-NEXT: # in Loop: Header=BB3_1 Depth=1 411; CHECK64-NEXT: movzbl (%rdi), %ecx # encoding: [0x0f,0xb6,0x0f] 412; CHECK64-NEXT: addl $-48, %ecx # encoding: [0x83,0xc1,0xd0] 413; CHECK64-NEXT: cmpl $10, %ecx # encoding: [0x83,0xf9,0x0a] 414; CHECK64-NEXT: .LBB3_9: # %if.else 415; CHECK64-NEXT: # in Loop: Header=BB3_1 Depth=1 416; CHECK64-NEXT: movl %r9d, %ecx # encoding: [0x44,0x89,0xc9] 417; CHECK64-NEXT: jb .LBB3_11 # encoding: [0x72,A] 418; CHECK64-NEXT: # fixup A - offset: 1, value: .LBB3_11-1, kind: FK_PCRel_1 419; CHECK64-NEXT: jmp .LBB3_13 # encoding: [0xeb,A] 420; CHECK64-NEXT: # fixup A - offset: 1, value: .LBB3_13-1, kind: FK_PCRel_1 421; CHECK64-NEXT: .LBB3_10: # %sw.bb22 422; CHECK64-NEXT: # in Loop: Header=BB3_1 Depth=1 423; CHECK64-NEXT: movzbl (%rdi), %ecx # encoding: [0x0f,0xb6,0x0f] 424; CHECK64-NEXT: addl $-48, %ecx # encoding: [0x83,0xc1,0xd0] 425; CHECK64-NEXT: cmpl $10, %ecx # encoding: [0x83,0xf9,0x0a] 426; CHECK64-NEXT: movl %r9d, %ecx # encoding: [0x44,0x89,0xc9] 427; CHECK64-NEXT: jae _Z20isValidIntegerSuffixN9__gnu_cxx17__normal_iteratorIPKcSsEES3_ # TAILCALL 428; CHECK64-NEXT: # encoding: [0x73,A] 429; CHECK64-NEXT: # fixup A - offset: 1, value: _Z20isValidIntegerSuffixN9__gnu_cxx17__normal_iteratorIPKcSsEES3_-1, kind: FK_PCRel_1 430; CHECK64-NEXT: .LBB3_11: # %for.inc 431; CHECK64-NEXT: # in Loop: Header=BB3_1 Depth=1 432; CHECK64-NEXT: incq %rdi # encoding: [0x48,0xff,0xc7] 433; CHECK64-NEXT: decq %rax # encoding: [0x48,0xff,0xc8] 434; CHECK64-NEXT: jmp .LBB3_1 # encoding: [0xeb,A] 435; CHECK64-NEXT: # fixup A - offset: 1, value: .LBB3_1-1, kind: FK_PCRel_1 436; CHECK64-NEXT: .LBB3_12: 437; CHECK64-NEXT: cmpl $2, %ecx # encoding: [0x83,0xf9,0x02] 438; CHECK64-NEXT: sete %al # encoding: [0x0f,0x94,0xc0] 439; CHECK64-NEXT: # kill: def $al killed $al killed $eax 440; CHECK64-NEXT: retq # encoding: [0xc3] 441; CHECK64-NEXT: .LBB3_13: 442; CHECK64-NEXT: xorl %eax, %eax # encoding: [0x31,0xc0] 443; CHECK64-NEXT: # kill: def $al killed $al killed $eax 444; CHECK64-NEXT: retq # encoding: [0xc3] 445; 446; WIN64-LABEL: pr31257: 447; WIN64: # %bb.0: # %entry 448; WIN64-NEXT: movq (%rcx), %rcx # encoding: [0x48,0x8b,0x09] 449; WIN64-NEXT: movq -24(%rcx), %r8 # encoding: [0x4c,0x8b,0x41,0xe8] 450; WIN64-NEXT: leaq (%rcx,%r8), %rdx # encoding: [0x4a,0x8d,0x14,0x01] 451; WIN64-NEXT: xorl %eax, %eax # encoding: [0x31,0xc0] 452; WIN64-NEXT: .LBB3_1: # %for.cond 453; WIN64-NEXT: # =>This Inner Loop Header: Depth=1 454; WIN64-NEXT: testq %r8, %r8 # encoding: [0x4d,0x85,0xc0] 455; WIN64-NEXT: je .LBB3_11 # encoding: [0x74,A] 456; WIN64-NEXT: # fixup A - offset: 1, value: .LBB3_11-1, kind: FK_PCRel_1 457; WIN64-NEXT: # %bb.2: # %for.body 458; WIN64-NEXT: # in Loop: Header=BB3_1 Depth=1 459; WIN64-NEXT: cmpl $2, %eax # encoding: [0x83,0xf8,0x02] 460; WIN64-NEXT: je .LBB3_9 # encoding: [0x74,A] 461; WIN64-NEXT: # fixup A - offset: 1, value: .LBB3_9-1, kind: FK_PCRel_1 462; WIN64-NEXT: # %bb.3: # %for.body 463; WIN64-NEXT: # in Loop: Header=BB3_1 Depth=1 464; WIN64-NEXT: cmpl $1, %eax # encoding: [0x83,0xf8,0x01] 465; WIN64-NEXT: je .LBB3_7 # encoding: [0x74,A] 466; WIN64-NEXT: # fixup A - offset: 1, value: .LBB3_7-1, kind: FK_PCRel_1 467; WIN64-NEXT: # %bb.4: # %for.body 468; WIN64-NEXT: # in Loop: Header=BB3_1 Depth=1 469; WIN64-NEXT: testl %eax, %eax # encoding: [0x85,0xc0] 470; WIN64-NEXT: jne .LBB3_10 # encoding: [0x75,A] 471; WIN64-NEXT: # fixup A - offset: 1, value: .LBB3_10-1, kind: FK_PCRel_1 472; WIN64-NEXT: # %bb.5: # %sw.bb 473; WIN64-NEXT: # in Loop: Header=BB3_1 Depth=1 474; WIN64-NEXT: movzbl (%rcx), %r9d # encoding: [0x44,0x0f,0xb6,0x09] 475; WIN64-NEXT: cmpl $43, %r9d # encoding: [0x41,0x83,0xf9,0x2b] 476; WIN64-NEXT: movl $1, %eax # encoding: [0xb8,0x01,0x00,0x00,0x00] 477; WIN64-NEXT: je .LBB3_10 # encoding: [0x74,A] 478; WIN64-NEXT: # fixup A - offset: 1, value: .LBB3_10-1, kind: FK_PCRel_1 479; WIN64-NEXT: # %bb.6: # %sw.bb 480; WIN64-NEXT: # in Loop: Header=BB3_1 Depth=1 481; WIN64-NEXT: cmpb $45, %r9b # encoding: [0x41,0x80,0xf9,0x2d] 482; WIN64-NEXT: je .LBB3_10 # encoding: [0x74,A] 483; WIN64-NEXT: # fixup A - offset: 1, value: .LBB3_10-1, kind: FK_PCRel_1 484; WIN64-NEXT: jmp .LBB3_8 # encoding: [0xeb,A] 485; WIN64-NEXT: # fixup A - offset: 1, value: .LBB3_8-1, kind: FK_PCRel_1 486; WIN64-NEXT: .LBB3_7: # %sw.bb14 487; WIN64-NEXT: # in Loop: Header=BB3_1 Depth=1 488; WIN64-NEXT: movzbl (%rcx), %r9d # encoding: [0x44,0x0f,0xb6,0x09] 489; WIN64-NEXT: .LBB3_8: # %if.else 490; WIN64-NEXT: # in Loop: Header=BB3_1 Depth=1 491; WIN64-NEXT: addl $-48, %r9d # encoding: [0x41,0x83,0xc1,0xd0] 492; WIN64-NEXT: movl $2, %eax # encoding: [0xb8,0x02,0x00,0x00,0x00] 493; WIN64-NEXT: cmpl $10, %r9d # encoding: [0x41,0x83,0xf9,0x0a] 494; WIN64-NEXT: jb .LBB3_10 # encoding: [0x72,A] 495; WIN64-NEXT: # fixup A - offset: 1, value: .LBB3_10-1, kind: FK_PCRel_1 496; WIN64-NEXT: jmp .LBB3_12 # encoding: [0xeb,A] 497; WIN64-NEXT: # fixup A - offset: 1, value: .LBB3_12-1, kind: FK_PCRel_1 498; WIN64-NEXT: .LBB3_9: # %sw.bb22 499; WIN64-NEXT: # in Loop: Header=BB3_1 Depth=1 500; WIN64-NEXT: movzbl (%rcx), %r9d # encoding: [0x44,0x0f,0xb6,0x09] 501; WIN64-NEXT: addl $-48, %r9d # encoding: [0x41,0x83,0xc1,0xd0] 502; WIN64-NEXT: movl $2, %eax # encoding: [0xb8,0x02,0x00,0x00,0x00] 503; WIN64-NEXT: cmpl $10, %r9d # encoding: [0x41,0x83,0xf9,0x0a] 504; WIN64-NEXT: jae _Z20isValidIntegerSuffixN9__gnu_cxx17__normal_iteratorIPKcSsEES3_ # TAILCALL 505; WIN64-NEXT: # encoding: [0x73,A] 506; WIN64-NEXT: # fixup A - offset: 1, value: _Z20isValidIntegerSuffixN9__gnu_cxx17__normal_iteratorIPKcSsEES3_-1, kind: FK_PCRel_1 507; WIN64-NEXT: .LBB3_10: # %for.inc 508; WIN64-NEXT: # in Loop: Header=BB3_1 Depth=1 509; WIN64-NEXT: incq %rcx # encoding: [0x48,0xff,0xc1] 510; WIN64-NEXT: decq %r8 # encoding: [0x49,0xff,0xc8] 511; WIN64-NEXT: jmp .LBB3_1 # encoding: [0xeb,A] 512; WIN64-NEXT: # fixup A - offset: 1, value: .LBB3_1-1, kind: FK_PCRel_1 513; WIN64-NEXT: .LBB3_11: 514; WIN64-NEXT: cmpl $2, %eax # encoding: [0x83,0xf8,0x02] 515; WIN64-NEXT: sete %al # encoding: [0x0f,0x94,0xc0] 516; WIN64-NEXT: # kill: def $al killed $al killed $eax 517; WIN64-NEXT: retq # encoding: [0xc3] 518; WIN64-NEXT: .LBB3_12: 519; WIN64-NEXT: xorl %eax, %eax # encoding: [0x31,0xc0] 520; WIN64-NEXT: # kill: def $al killed $al killed $eax 521; WIN64-NEXT: retq # encoding: [0xc3] 522entry: 523 %_M_p.i.i = getelementptr inbounds %"class.std::basic_string", %"class.std::basic_string"* %s, i64 0, i32 0, i32 0 524 %0 = load i8*, i8** %_M_p.i.i, align 8 525 %arrayidx.i.i.i54 = getelementptr inbounds i8, i8* %0, i64 -24 526 %_M_length.i.i55 = bitcast i8* %arrayidx.i.i.i54 to i64* 527 %1 = load i64, i64* %_M_length.i.i55, align 8 528 %add.ptr.i56 = getelementptr inbounds i8, i8* %0, i64 %1 529 br label %for.cond 530 531for.cond: ; preds = %for.inc, %entry 532 %it.sroa.0.0 = phi i8* [ %0, %entry ], [ %incdec.ptr.i, %for.inc ] 533 %state.0 = phi i32 [ 0, %entry ], [ %state.1, %for.inc ] 534 %cmp.i = icmp eq i8* %it.sroa.0.0, %add.ptr.i56 535 br i1 %cmp.i, label %5, label %for.body 536 537for.body: ; preds = %for.cond 538 switch i32 %state.0, label %for.inc [ 539 i32 0, label %sw.bb 540 i32 1, label %sw.bb14 541 i32 2, label %sw.bb22 542 ] 543 544sw.bb: ; preds = %for.body 545 %2 = load i8, i8* %it.sroa.0.0, align 1 546 switch i8 %2, label %if.else [ 547 i8 43, label %for.inc 548 i8 45, label %for.inc 549 ] 550 551if.else: ; preds = %sw.bb 552 %conv9 = zext i8 %2 to i32 553 %isdigittmp45 = add nsw i32 %conv9, -48 554 %isdigit46 = icmp ult i32 %isdigittmp45, 10 555 br i1 %isdigit46, label %for.inc, label %cleanup.thread.loopexit 556 557sw.bb14: ; preds = %for.body 558 %3 = load i8, i8* %it.sroa.0.0, align 1 559 %conv16 = zext i8 %3 to i32 560 %isdigittmp43 = add nsw i32 %conv16, -48 561 %isdigit44 = icmp ult i32 %isdigittmp43, 10 562 br i1 %isdigit44, label %for.inc, label %cleanup.thread.loopexit 563 564sw.bb22: ; preds = %for.body 565 %4 = load i8, i8* %it.sroa.0.0, align 1 566 %conv24 = zext i8 %4 to i32 567 %isdigittmp = add nsw i32 %conv24, -48 568 %isdigit = icmp ult i32 %isdigittmp, 10 569 br i1 %isdigit, label %for.inc, label %if.else28 570 571; Make sure Machine Copy Propagation doesn't delete the mov to %ecx becaue it 572; thinks the conditional tail call clobbers it. 573 574if.else28: ; preds = %sw.bb22 575 %call34 = tail call zeroext i1 @_Z20isValidIntegerSuffixN9__gnu_cxx17__normal_iteratorIPKcSsEES3_(i8* nonnull %it.sroa.0.0, i8* %add.ptr.i56) 576 br label %cleanup.thread 577 578for.inc: ; preds = %sw.bb, %sw.bb, %sw.bb22, %sw.bb14, %if.else, %for.body 579 %state.1 = phi i32 [ %state.0, %for.body ], [ 1, %sw.bb ], [ 2, %if.else ], [ 2, %sw.bb14 ], [ 2, %sw.bb22 ], [ 1, %sw.bb ] 580 %incdec.ptr.i = getelementptr inbounds i8, i8* %it.sroa.0.0, i64 1 581 br label %for.cond 582 583; <label>:5: ; preds = %for.cond 584 %cmp37 = icmp eq i32 %state.0, 2 585 br label %cleanup.thread 586 587cleanup.thread.loopexit: ; preds = %if.else, %sw.bb14 588 br label %cleanup.thread 589 590cleanup.thread: ; preds = %cleanup.thread.loopexit, %if.else28, %5 591 %6 = phi i1 [ %cmp37, %5 ], [ %call34, %if.else28 ], [ false, %cleanup.thread.loopexit ] 592 ret i1 %6 593} 594