diff --git a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp --- a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp @@ -2230,6 +2230,11 @@ if (!MRI.hasOneUse(LoadReg)) return false; + // If the register has fixups, there may be additional uses through a + // different alias of the register. + if (FuncInfo.RegsWithFixups.contains(LoadReg)) + return false; + MachineRegisterInfo::reg_iterator RI = MRI.reg_begin(LoadReg); MachineInstr *User = RI->getParent(); diff --git a/llvm/test/CodeGen/X86/fast-isel-load-bitcast-fold.ll b/llvm/test/CodeGen/X86/fast-isel-load-bitcast-fold.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/X86/fast-isel-load-bitcast-fold.ll @@ -0,0 +1,36 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -O0 -mtriple=x86_64-- -verify-machineinstrs < %s | FileCheck %s + +define void @repro(i8** %a0, i1 %a1) nounwind { +; CHECK-LABEL: repro: +; CHECK: # %bb.0: +; CHECK-NEXT: subq $24, %rsp +; CHECK-NEXT: movb %sil, %al +; CHECK-NEXT: movb %al, {{[-0-9]+}}(%r{{[sb]}}p) # 1-byte Spill +; CHECK-NEXT: movq (%rdi), %rax +; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; CHECK-NEXT: callq *%rax +; CHECK-NEXT: movb {{[-0-9]+}}(%r{{[sb]}}p), %al # 1-byte Reload +; CHECK-NEXT: testb $1, %al +; CHECK-NEXT: jne .LBB0_1 +; CHECK-NEXT: jmp .LBB0_2 +; CHECK-NEXT: .LBB0_1: # %bb1 +; CHECK-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rax # 8-byte Reload +; CHECK-NEXT: callq *%rax +; CHECK-NEXT: addq $24, %rsp +; CHECK-NEXT: retq +; CHECK-NEXT: .LBB0_2: # %bb2 +; CHECK-NEXT: addq $24, %rsp +; CHECK-NEXT: retq + %tmp0 = load i8*, i8** %a0 + %tmp1 = bitcast i8* %tmp0 to void ()* + call void %tmp1() + br i1 %a1, label %bb1, label %bb2 + +bb1: + call void %tmp1() + ret void + +bb2: + ret void +}