1 # RUN: llc -run-pass implicit-null-checks -mtriple=x86_64-apple-macosx -o - %s | FileCheck %s 2 3 --- | 4 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" 5 target triple = "x86_64-apple-macosx" 6 7 ;; Positive test 8 define i32 @imp_null_check_with_bitwise_op_0(i32* %x, i32 %val) { 9 entry: 10 br i1 undef, label %is_null, label %not_null, !make.implicit !0 11 12 is_null: 13 ret i32 42 14 15 not_null: 16 br i1 undef, label %ret_100, label %ret_200 17 18 ret_100: 19 ret i32 100 20 21 ret_200: 22 ret i32 200 23 } 24 25 ;; Negative test. The regalloc is such that we cannot hoist the 26 ;; instruction materializing 2200000 into %eax 27 define i32 @imp_null_check_with_bitwise_op_1(i32* %x, i32 %val, i32* %ptr) { 28 entry: 29 br i1 undef, label %is_null, label %not_null, !make.implicit !0 30 31 is_null: 32 ret i32 undef 33 34 not_null: 35 br i1 undef, label %ret_100, label %ret_200 36 37 ret_100: 38 ret i32 100 39 40 ret_200: 41 ret i32 200 42 } 43 44 ;; Negative test: IR is identical to 45 ;; @imp_null_check_with_bitwise_op_0 but MIR differs. 46 define i32 @imp_null_check_with_bitwise_op_2(i32* %x, i32 %val) { 47 entry: 48 br i1 undef, label %is_null, label %not_null, !make.implicit !0 49 50 is_null: 51 ret i32 42 52 53 not_null: 54 br i1 undef, label %ret_100, label %ret_200 55 56 ret_100: 57 ret i32 100 58 59 ret_200: 60 ret i32 200 61 } 62 63 ;; Negative test: IR is identical to 64 ;; @imp_null_check_with_bitwise_op_0 but MIR differs. 65 define i32 @imp_null_check_with_bitwise_op_3(i32* %x, i32 %val) { 66 entry: 67 br i1 undef, label %is_null, label %not_null, !make.implicit !0 68 69 is_null: 70 ret i32 42 71 72 not_null: 73 br i1 undef, label %ret_100, label %ret_200 74 75 ret_100: 76 ret i32 100 77 78 ret_200: 79 ret i32 200 80 } 81 82 !0 = !{} 83 ... 84 --- 85 name: imp_null_check_with_bitwise_op_0 86 # CHECK-LABEL: name: imp_null_check_with_bitwise_op_0 87 alignment: 4 88 allVRegsAllocated: true 89 tracksRegLiveness: true 90 tracksSubRegLiveness: false 91 liveins: 92 - { reg: '%rdi' } 93 - { reg: '%esi' } 94 # CHECK: bb.0.entry: 95 # CHECK: %eax = MOV32ri 2200000 96 # CHECK-NEXT: %eax = FAULTING_LOAD_OP %bb.3.is_null, {{[0-9]+}}, killed %eax, killed %rdi, 1, _, 0, _, implicit-def dead %eflags :: (load 4 from %ir.x) 97 # CHECK-NEXT: JMP_1 %bb.1.not_null 98 99 body: | 100 bb.0.entry: 101 successors: %bb.3.is_null, %bb.1.not_null 102 liveins: %esi, %rdi 103 104 TEST64rr %rdi, %rdi, implicit-def %eflags 105 JE_1 %bb.3.is_null, implicit %eflags 106 107 bb.1.not_null: 108 successors: %bb.4.ret_100, %bb.2.ret_200 109 liveins: %esi, %rdi 110 111 %eax = MOV32ri 2200000 112 %eax = AND32rm killed %eax, killed %rdi, 1, _, 0, _, implicit-def dead %eflags :: (load 4 from %ir.x) 113 CMP32rr killed %eax, killed %esi, implicit-def %eflags 114 JE_1 %bb.4.ret_100, implicit %eflags 115 116 bb.2.ret_200: 117 %eax = MOV32ri 200 118 RET 0, %eax 119 120 bb.3.is_null: 121 %eax = MOV32ri 42 122 RET 0, %eax 123 124 bb.4.ret_100: 125 %eax = MOV32ri 100 126 RET 0, %eax 127 128 ... 129 --- 130 name: imp_null_check_with_bitwise_op_1 131 alignment: 4 132 allVRegsAllocated: true 133 isSSA: false 134 tracksRegLiveness: true 135 tracksSubRegLiveness: false 136 liveins: 137 - { reg: '%rdi' } 138 - { reg: '%esi' } 139 - { reg: '%rdx' } 140 # CHECK: bb.0.entry: 141 # CHECK: %eax = MOV32rm killed %rdx, 1, _, 0, _ :: (volatile load 4 from %ir.ptr) 142 # CHECK-NEXT: TEST64rr %rdi, %rdi, implicit-def %eflags 143 # CHECK-NEXT: JE_1 %bb.3.is_null, implicit %eflags 144 145 body: | 146 bb.0.entry: 147 successors: %bb.3.is_null, %bb.1.not_null 148 liveins: %esi, %rdi, %rdx 149 150 %eax = MOV32rm killed %rdx, 1, _, 0, _ :: (volatile load 4 from %ir.ptr) 151 TEST64rr %rdi, %rdi, implicit-def %eflags 152 JE_1 %bb.3.is_null, implicit %eflags 153 154 bb.1.not_null: 155 successors: %bb.4.ret_100, %bb.2.ret_200 156 liveins: %esi, %rdi 157 158 %eax = MOV32ri 2200000 159 %eax = AND32rm killed %eax, killed %rdi, 1, _, 0, _, implicit-def dead %eflags :: (load 4 from %ir.x) 160 CMP32rr killed %eax, killed %esi, implicit-def %eflags 161 JE_1 %bb.4.ret_100, implicit %eflags 162 163 bb.2.ret_200: 164 successors: %bb.3.is_null 165 166 %eax = MOV32ri 200 167 168 bb.3.is_null: 169 liveins: %eax, %ah, %al, %ax, %bh, %bl, %bp, %bpl, %bx, %eax, %ebp, %ebx, %rax, %rbp, %rbx, %r12, %r13, %r14, %r15, %r12b, %r13b, %r14b, %r15b, %r12d, %r13d, %r14d, %r15d, %r12w, %r13w, %r14w, %r15w 170 171 RET 0, %eax 172 173 bb.4.ret_100: 174 %eax = MOV32ri 100 175 RET 0, %eax 176 177 ... 178 --- 179 name: imp_null_check_with_bitwise_op_2 180 # CHECK-LABEL: name: imp_null_check_with_bitwise_op_2 181 alignment: 4 182 allVRegsAllocated: true 183 tracksRegLiveness: true 184 tracksSubRegLiveness: false 185 liveins: 186 - { reg: '%rdi' } 187 - { reg: '%esi' } 188 # CHECK: bb.0.entry: 189 # CHECK: TEST64rr %rdi, %rdi, implicit-def %eflags 190 # CHECK-NEXT: JE_1 %bb.3.is_null, implicit %eflags 191 192 body: | 193 bb.0.entry: 194 successors: %bb.3.is_null, %bb.1.not_null 195 liveins: %esi, %rdi 196 197 TEST64rr %rdi, %rdi, implicit-def %eflags 198 JE_1 %bb.3.is_null, implicit %eflags 199 200 bb.1.not_null: 201 successors: %bb.4.ret_100, %bb.2.ret_200 202 liveins: %esi, %rdi 203 204 %eax = MOV32ri 2200000 205 %eax = ADD32ri killed %eax, 100, implicit-def dead %eflags 206 %eax = AND32rm killed %eax, killed %rdi, 1, _, 0, _, implicit-def dead %eflags :: (load 4 from %ir.x) 207 CMP32rr killed %eax, killed %esi, implicit-def %eflags 208 JE_1 %bb.4.ret_100, implicit %eflags 209 210 bb.2.ret_200: 211 %eax = MOV32ri 200 212 RET 0, %eax 213 214 bb.3.is_null: 215 %eax = MOV32ri 42 216 RET 0, %eax 217 218 bb.4.ret_100: 219 %eax = MOV32ri 100 220 RET 0, %eax 221 222 ... 223 --- 224 name: imp_null_check_with_bitwise_op_3 225 # CHECK-LABEL: name: imp_null_check_with_bitwise_op_3 226 alignment: 4 227 allVRegsAllocated: true 228 tracksRegLiveness: true 229 tracksSubRegLiveness: false 230 liveins: 231 - { reg: '%rdi' } 232 - { reg: '%rsi' } 233 # CHECK: bb.0.entry: 234 # CHECK: TEST64rr %rdi, %rdi, implicit-def %eflags 235 # CHECK-NEXT: JE_1 %bb.3.is_null, implicit %eflags 236 237 body: | 238 bb.0.entry: 239 successors: %bb.3.is_null, %bb.1.not_null 240 liveins: %rsi, %rdi 241 242 TEST64rr %rdi, %rdi, implicit-def %eflags 243 JE_1 %bb.3.is_null, implicit %eflags 244 245 bb.1.not_null: 246 successors: %bb.4.ret_100, %bb.2.ret_200 247 liveins: %rsi, %rdi 248 249 %rdi = MOV64ri 5000 250 %rdi = AND64rm killed %rdi, killed %rdi, 1, _, 0, _, implicit-def dead %eflags :: (load 4 from %ir.x) 251 CMP64rr killed %rdi, killed %rsi, implicit-def %eflags 252 JE_1 %bb.4.ret_100, implicit %eflags 253 254 bb.2.ret_200: 255 %eax = MOV32ri 200 256 RET 0, %eax 257 258 bb.3.is_null: 259 %eax = MOV32ri 42 260 RET 0, %eax 261 262 bb.4.ret_100: 263 %eax = MOV32ri 100 264 RET 0, %eax 265 266 ... 267