From: Sanjoy Das Date: Wed, 16 Nov 2016 21:45:22 +0000 (+0000) Subject: [ImplicitNullChecks] Do not not handle call MachineInstrs X-Git-Tag: android-x86-7.1-r4~24379 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=99e15d01ed97edcdfeca21c77bd627c3dc693214;p=android-x86%2Fexternal-llvm.git [ImplicitNullChecks] Do not not handle call MachineInstrs We don't track callee clobbered registers correctly, so avoid hoisting across calls. Note: for this bug to trigger we need a `readonly` call target, since we already have logic to not hoist across potentially storing instructions either. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@287159 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/ImplicitNullChecks.cpp b/lib/CodeGen/ImplicitNullChecks.cpp index 7f5c9b712b2..6c35aaac7d2 100644 --- a/lib/CodeGen/ImplicitNullChecks.cpp +++ b/lib/CodeGen/ImplicitNullChecks.cpp @@ -187,7 +187,10 @@ void HazardDetector::rememberInstruction(MachineInstr *MI) { assert(!isClobbered() && "Don't add instructions to a clobbered hazard detector"); - if (MI->mayStore() || MI->hasUnmodeledSideEffects()) { + // There may be readonly calls that we can handle in theory, but for + // now we don't bother since we don't handle callee clobbered + // registers. + if (MI->isCall() || MI->mayStore() || MI->hasUnmodeledSideEffects()) { hasSeenClobber = true; return; } diff --git a/test/CodeGen/X86/implicit-null-checks.mir b/test/CodeGen/X86/implicit-null-checks.mir index 16a1a1ca2dc..eb3c0d55cf7 100644 --- a/test/CodeGen/X86/implicit-null-checks.mir +++ b/test/CodeGen/X86/implicit-null-checks.mir @@ -79,6 +79,22 @@ ret i32 200 } + declare void @f() readonly + + define i32 @no_hoist_across_call(i32* %ptr) { + entry: + %is_null = icmp eq i32* %ptr, null + br i1 %is_null, label %leave, label %stay, !make.implicit !0 + + stay: + call void @f() + %val = load i32, i32* %ptr + ret i32 %val + + leave: + ret i32 0 + } + !0 = !{} ... --- @@ -255,3 +271,44 @@ body: | RET 0, %eax ... +--- +name: no_hoist_across_call +# CHECK-LABEL: name: no_hoist_across_call +alignment: 4 +tracksRegLiveness: true +liveins: + - { reg: '%rdi' } +calleeSavedRegisters: [ '%bh', '%bl', '%bp', '%bpl', '%bx', '%ebp', '%ebx', + '%rbp', '%rbx', '%r12', '%r13', '%r14', '%r15', + '%r12b', '%r13b', '%r14b', '%r15b', '%r12d', '%r13d', + '%r14d', '%r15d', '%r12w', '%r13w', '%r14w', '%r15w' ] +# CHECK: body: +# CHECK-NOT: FAULTING_LOAD_OP +# CHECK: bb.1.stay: +# CHECK: CALL64pcrel32 +body: | + bb.0.entry: + successors: %bb.2.leave, %bb.1.stay + liveins: %rdi, %rbx + + frame-setup PUSH64r killed %rbx, implicit-def %rsp, implicit %rsp + CFI_INSTRUCTION def_cfa_offset 16 + CFI_INSTRUCTION offset %rbx, -16 + %rbx = MOV64rr %rdi + TEST64rr %rbx, %rbx, implicit-def %eflags + JE_1 %bb.2.leave, implicit killed %eflags + + bb.1.stay: + liveins: %rbx + + CALL64pcrel32 @f, csr_64, implicit %rsp, implicit-def %rsp + %eax = MOV32rm killed %rbx, 1, _, 0, _ :: (load 4 from %ir.ptr) + %rbx = POP64r implicit-def %rsp, implicit %rsp + RETQ %eax + + bb.2.leave: + %eax = XOR32rr undef %eax, undef %eax, implicit-def dead %eflags + %rbx = POP64r implicit-def %rsp, implicit %rsp + RETQ %eax + +...