1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=i686-unknown -verify-machineinstrs < %s | FileCheck %s 3; RUN: opt < %s -codegenprepare -S -mtriple=x86_64-unknown-unknown | FileCheck --check-prefix=CHECK-CGP %s 4; RUN: opt < %s -codegenprepare -cgpp-huge-func=0 -S -mtriple=x86_64-unknown-unknown | FileCheck --check-prefix=CHECK-CGP %s 5 6@A = global i32 zeroinitializer 7@B = global i32 zeroinitializer 8@C = global i32 zeroinitializer 9 10; Test that 'and' is sunk into bb0. 11define i32 @and_sink1(i32 %a, i1 %c) { 12; CHECK-LABEL: and_sink1: 13; CHECK: # %bb.0: 14; CHECK-NEXT: testb $1, {{[0-9]+}}(%esp) 15; CHECK-NEXT: je .LBB0_3 16; CHECK-NEXT: # %bb.1: # %bb0 17; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax 18; CHECK-NEXT: testb $4, %al 19; CHECK-NEXT: movl $0, A 20; CHECK-NEXT: jne .LBB0_3 21; CHECK-NEXT: # %bb.2: # %bb1 22; CHECK-NEXT: movl $1, %eax 23; CHECK-NEXT: retl 24; CHECK-NEXT: .LBB0_3: # %bb2 25; CHECK-NEXT: xorl %eax, %eax 26; CHECK-NEXT: retl 27 28; CHECK-CGP-LABEL: @and_sink1( 29; CHECK-CGP-NOT: and i32 30 %and = and i32 %a, 4 31 br i1 %c, label %bb0, label %bb2 32bb0: 33; CHECK-CGP-LABEL: bb0: 34; CHECK-CGP: and i32 35; CHECK-CGP-NEXT: icmp eq i32 36; CHECK-CGP-NEXT: store 37; CHECK-CGP-NEXT: br 38 %cmp = icmp eq i32 %and, 0 39 store i32 0, ptr @A 40 br i1 %cmp, label %bb1, label %bb2 41bb1: 42 ret i32 1 43bb2: 44 ret i32 0 45} 46 47; Test that both 'and' and cmp get sunk to bb1. 48define i32 @and_sink2(i32 %a, i1 %c, i1 %c2) { 49; CHECK-LABEL: and_sink2: 50; CHECK: # %bb.0: 51; CHECK-NEXT: movl $0, A 52; CHECK-NEXT: testb $1, {{[0-9]+}}(%esp) 53; CHECK-NEXT: je .LBB1_5 54; CHECK-NEXT: # %bb.1: # %bb0.preheader 55; CHECK-NEXT: movzbl {{[0-9]+}}(%esp), %eax 56; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx 57; CHECK-NEXT: .p2align 4 58; CHECK-NEXT: .LBB1_2: # %bb0 59; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 60; CHECK-NEXT: movl $0, B 61; CHECK-NEXT: testb $1, %al 62; CHECK-NEXT: je .LBB1_5 63; CHECK-NEXT: # %bb.3: # %bb1 64; CHECK-NEXT: # in Loop: Header=BB1_2 Depth=1 65; CHECK-NEXT: testb $4, %cl 66; CHECK-NEXT: movl $0, C 67; CHECK-NEXT: jne .LBB1_2 68; CHECK-NEXT: # %bb.4: # %bb2 69; CHECK-NEXT: movl $1, %eax 70; CHECK-NEXT: retl 71; CHECK-NEXT: .LBB1_5: # %bb3 72; CHECK-NEXT: xorl %eax, %eax 73; CHECK-NEXT: retl 74 75; CHECK-CGP-LABEL: @and_sink2( 76; CHECK-CGP-NOT: and i32 77 %and = and i32 %a, 4 78 store i32 0, ptr @A 79 br i1 %c, label %bb0, label %bb3 80bb0: 81; CHECK-CGP-LABEL: bb0: 82; CHECK-CGP-NOT: and i32 83; CHECK-CGP-NOT: icmp 84 %cmp = icmp eq i32 %and, 0 85 store i32 0, ptr @B 86 br i1 %c2, label %bb1, label %bb3 87bb1: 88; CHECK-CGP-LABEL: bb1: 89; CHECK-CGP: and i32 90; CHECK-CGP-NEXT: icmp eq i32 91; CHECK-CGP-NEXT: store 92; CHECK-CGP-NEXT: br 93 store i32 0, ptr @C 94 br i1 %cmp, label %bb2, label %bb0 95bb2: 96 ret i32 1 97bb3: 98 ret i32 0 99} 100 101; Test that CodeGenPrepare doesn't get stuck in a loop sinking and hoisting a masked load. 102define i32 @and_sink3(i1 %c, ptr %p) { 103; CHECK-LABEL: and_sink3: 104; CHECK: # %bb.0: 105; CHECK-NEXT: testb $1, {{[0-9]+}}(%esp) 106; CHECK-NEXT: je .LBB2_3 107; CHECK-NEXT: # %bb.1: # %bb0 108; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax 109; CHECK-NEXT: movzbl (%eax), %eax 110; CHECK-NEXT: testl %eax, %eax 111; CHECK-NEXT: movl $0, A 112; CHECK-NEXT: je .LBB2_2 113; CHECK-NEXT: .LBB2_3: # %bb2 114; CHECK-NEXT: xorl %eax, %eax 115; CHECK-NEXT: retl 116; CHECK-NEXT: .LBB2_2: # %bb1 117; CHECK-NEXT: movl $1, %eax 118; CHECK-NEXT: retl 119 120; CHECK-CGP-LABEL: @and_sink3( 121; CHECK-CGP: load i32 122; CHECK-CGP-NEXT: and i32 123 %load = load i32, ptr %p 124 %and = and i32 %load, 255 125 br i1 %c, label %bb0, label %bb2 126bb0: 127; CHECK-CGP-LABEL: bb0: 128; CHECK-CGP-NOT: and i32 129; CHECK-CGP: icmp eq i32 130 %cmp = icmp eq i32 %and, 0 131 store i32 0, ptr @A 132 br i1 %cmp, label %bb1, label %bb2 133bb1: 134 ret i32 1 135bb2: 136 ret i32 0 137} 138 139; Test that CodeGenPrepare sinks/duplicates non-immediate 'and'. 140define i32 @and_sink4(i32 %a, i32 %b, i1 %c) { 141; CHECK-LABEL: and_sink4: 142; CHECK: # %bb.0: 143; CHECK-NEXT: testb $1, {{[0-9]+}}(%esp) 144; CHECK-NEXT: je .LBB3_4 145; CHECK-NEXT: # %bb.1: # %bb0 146; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax 147; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx 148; CHECK-NEXT: testl %eax, %ecx 149; CHECK-NEXT: movl $0, A 150; CHECK-NEXT: jne .LBB3_4 151; CHECK-NEXT: # %bb.2: # %bb1 152; CHECK-NEXT: leal (%ecx,%eax), %edx 153; CHECK-NEXT: testl %eax, %ecx 154; CHECK-NEXT: movl %edx, B 155; CHECK-NEXT: je .LBB3_3 156; CHECK-NEXT: .LBB3_4: # %bb3 157; CHECK-NEXT: xorl %eax, %eax 158; CHECK-NEXT: retl 159; CHECK-NEXT: .LBB3_3: # %bb2 160; CHECK-NEXT: movl $1, %eax 161; CHECK-NEXT: retl 162 163; CHECK-CGP-LABEL: @and_sink4( 164; CHECK-CGP-NOT: and i32 165; CHECK-CGP-NOT: icmp 166 %and = and i32 %a, %b 167 %cmp = icmp eq i32 %and, 0 168 br i1 %c, label %bb0, label %bb3 169bb0: 170; CHECK-CGP-LABEL: bb0: 171; CHECK-CGP: and i32 172; CHECK-CGP-NEXT: icmp eq i32 173 store i32 0, ptr @A 174 br i1 %cmp, label %bb1, label %bb3 175bb1: 176; CHECK-CGP-LABEL: bb1: 177; CHECK-CGP: and i32 178; CHECK-CGP-NEXT: icmp eq i32 179 %add = add i32 %a, %b 180 store i32 %add, ptr @B 181 br i1 %cmp, label %bb2, label %bb3 182bb2: 183 ret i32 1 184bb3: 185 ret i32 0 186} 187 188 189; Test that CodeGenPrepare doesn't sink/duplicate non-immediate 'and' 190; when it would increase register pressure. 191define i32 @and_sink5(i32 %a, i32 %b, i32 %a2, i32 %b2, i1 %c) { 192; CHECK-LABEL: and_sink5: 193; CHECK: # %bb.0: 194; CHECK-NEXT: testb $1, {{[0-9]+}}(%esp) 195; CHECK-NEXT: je .LBB4_4 196; CHECK-NEXT: # %bb.1: # %bb0 197; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax 198; CHECK-NEXT: andl {{[0-9]+}}(%esp), %eax 199; CHECK-NEXT: movl $0, A 200; CHECK-NEXT: jne .LBB4_4 201; CHECK-NEXT: # %bb.2: # %bb1 202; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx 203; CHECK-NEXT: addl {{[0-9]+}}(%esp), %ecx 204; CHECK-NEXT: testl %eax, %eax 205; CHECK-NEXT: movl %ecx, B 206; CHECK-NEXT: je .LBB4_3 207; CHECK-NEXT: .LBB4_4: # %bb3 208; CHECK-NEXT: xorl %eax, %eax 209; CHECK-NEXT: retl 210; CHECK-NEXT: .LBB4_3: # %bb2 211; CHECK-NEXT: movl $1, %eax 212; CHECK-NEXT: retl 213 214; CHECK-CGP-LABEL: @and_sink5( 215; CHECK-CGP: and i32 216; CHECK-CGP-NOT: icmp 217 %and = and i32 %a, %b 218 %cmp = icmp eq i32 %and, 0 219 br i1 %c, label %bb0, label %bb3 220bb0: 221; CHECK-CGP-LABEL: bb0: 222; CHECK-CGP-NOT: and i32 223; CHECK-CGP: icmp eq i32 224 store i32 0, ptr @A 225 br i1 %cmp, label %bb1, label %bb3 226bb1: 227; CHECK-CGP-LABEL: bb1: 228; CHECK-CGP-NOT: and i32 229; CHECK-CGP: icmp eq i32 230 %add = add i32 %a2, %b2 231 store i32 %add, ptr @B 232 br i1 %cmp, label %bb2, label %bb3 233bb2: 234 ret i32 1 235bb3: 236 ret i32 0 237} 238