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