diff --git a/llvm/include/llvm/CodeGen/FastISel.h b/llvm/include/llvm/CodeGen/FastISel.h index 7af25db90479..b0503f0391fe 100644 --- a/llvm/include/llvm/CodeGen/FastISel.h +++ b/llvm/include/llvm/CodeGen/FastISel.h @@ -575,6 +575,10 @@ private: /// correspond to a different MBB than the end. bool HandlePHINodesInSuccessorBlocks(const BasicBlock *LLVMBB); + /// \brief Helper for materializeRegForValue to materialize a constant in a + /// target-independent way. + unsigned MaterializeConstant(const Value *V, MVT VT); + /// Helper for getRegForVale. This function is called when the value isn't /// already available in a register and must be materialized with new /// instructions. diff --git a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp index 6be5f8a57e2b..ec0531e04d4e 100644 --- a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp @@ -198,29 +198,24 @@ unsigned FastISel::getRegForValue(const Value *V) { return Reg; } -/// materializeRegForValue - Helper for getRegForValue. This function is -/// called when the value isn't already available in a register and must -/// be materialized with new instructions. -unsigned FastISel::materializeRegForValue(const Value *V, MVT VT) { +unsigned FastISel::MaterializeConstant(const Value *V, MVT VT) { unsigned Reg = 0; - if (const ConstantInt *CI = dyn_cast(V)) { if (CI->getValue().getActiveBits() <= 64) Reg = FastEmit_i(VT, VT, ISD::Constant, CI->getZExtValue()); - } else if (isa(V)) { + } else if (isa(V)) Reg = TargetMaterializeAlloca(cast(V)); - } else if (isa(V)) { + else if (isa(V)) // Translate this as an integer zero so that it can be // local-CSE'd with actual integer zeros. Reg = getRegForValue(Constant::getNullValue(DL.getIntPtrType(V->getContext()))); - } else if (const ConstantFP *CF = dyn_cast(V)) { - if (CF->isNullValue()) { + else if (const ConstantFP *CF = dyn_cast(V)) { + if (CF->isNullValue()) Reg = TargetMaterializeFloatZero(CF); - } else { + else // Try to emit the constant directly. Reg = FastEmit_f(VT, VT, ISD::ConstantFP, CF); - } if (!Reg) { // Try to emit the constant by using an integer constant with a cast. @@ -253,15 +248,26 @@ unsigned FastISel::materializeRegForValue(const Value *V, MVT VT) { BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(TargetOpcode::IMPLICIT_DEF), Reg); } + return Reg; +} - // If target-independent code couldn't handle the value, give target-specific - // code a try. - if (!Reg && isa(V)) +/// materializeRegForValue - Helper for getRegForValue. This function is +/// called when the value isn't already available in a register and must +/// be materialized with new instructions. +unsigned FastISel::materializeRegForValue(const Value *V, MVT VT) { + unsigned Reg = 0; + // Give the target-specific code a try first. + if (isa(V)) Reg = TargetMaterializeConstant(cast(V)); + // If target-specific code couldn't or didn't want to handle the value, then + // give target-independent code a try. + if (!Reg) + Reg = MaterializeConstant(V, VT); + // Don't cache constant materializations in the general ValueMap. // To do so would require tracking what uses they dominate. - if (Reg != 0) { + if (Reg) { LocalValueMap[V] = Reg; LastLocalValue = MRI.getVRegDef(Reg); } diff --git a/llvm/test/CodeGen/ARM/fast-isel-call.ll b/llvm/test/CodeGen/ARM/fast-isel-call.ll index 9d9e341647ab..74b31bd9e67f 100644 --- a/llvm/test/CodeGen/ARM/fast-isel-call.ll +++ b/llvm/test/CodeGen/ARM/fast-isel-call.ll @@ -117,17 +117,11 @@ entry: ; ARM-LONG: blx [[R]] ; THUMB: @t10 ; THUMB: movs [[R0:l?r[0-9]*]], #0 -; THUMB: movt [[R0]], #0 ; THUMB: movs [[R1:l?r[0-9]*]], #248 -; THUMB: movt [[R1]], #0 ; THUMB: movs [[R2:l?r[0-9]*]], #187 -; THUMB: movt [[R2]], #0 ; THUMB: movs [[R3:l?r[0-9]*]], #28 -; THUMB: movt [[R3]], #0 ; THUMB: movw [[R4:l?r[0-9]*]], #40 -; THUMB: movt [[R4]], #0 ; THUMB: movw [[R5:l?r[0-9]*]], #186 -; THUMB: movt [[R5]], #0 ; THUMB: and [[R0]], [[R0]], #255 ; THUMB: and [[R1]], [[R1]], #255 ; THUMB: and [[R2]], [[R2]], #255 diff --git a/llvm/test/CodeGen/ARM/fast-isel-deadcode.ll b/llvm/test/CodeGen/ARM/fast-isel-deadcode.ll index 5e6666c47d3e..c3eed30692b8 100644 --- a/llvm/test/CodeGen/ARM/fast-isel-deadcode.ll +++ b/llvm/test/CodeGen/ARM/fast-isel-deadcode.ll @@ -14,7 +14,6 @@ entry: ; THUMB-NOT: ldr ; THUMB-NOT: sxtb ; THUMB: movs r0, #0 -; THUMB: movt r0, #0 ; THUMB: pop ret i32 0 } diff --git a/llvm/test/CodeGen/ARM/fast-isel-intrinsic.ll b/llvm/test/CodeGen/ARM/fast-isel-intrinsic.ll index 089209e45fc3..b09931dc4e2f 100644 --- a/llvm/test/CodeGen/ARM/fast-isel-intrinsic.ll +++ b/llvm/test/CodeGen/ARM/fast-isel-intrinsic.ll @@ -31,9 +31,7 @@ define void @t1() nounwind ssp { ; THUMB: {{(movt r0, :upper16:_?message1)|(ldr r0, \[r0\])}} ; THUMB: adds r0, #5 ; THUMB: movs r1, #64 -; THUMB: movt r1, #0 ; THUMB: movs r2, #10 -; THUMB: movt r2, #0 ; THUMB: and r1, r1, #255 ; THUMB: bl {{_?}}memset ; THUMB-LONG-LABEL: t1: @@ -71,7 +69,6 @@ define void @t2() nounwind ssp { ; THUMB: adds r1, r0, #4 ; THUMB: adds r0, #16 ; THUMB: movs r2, #17 -; THUMB: movt r2, #0 ; THUMB: str r0, [sp[[SLOT:[, #0-9]*]]] @ 4-byte Spill ; THUMB: mov r0, r1 ; THUMB: ldr r1, [sp[[SLOT]]] @ 4-byte Reload @@ -109,7 +106,6 @@ define void @t3() nounwind ssp { ; THUMB: adds r1, r0, #4 ; THUMB: adds r0, #16 ; THUMB: movs r2, #10 -; THUMB: movt r2, #0 ; THUMB: str r0, [sp[[SLOT:[, #0-9]*]]] @ 4-byte Spill ; THUMB: mov r0, r1 ; THUMB: ldr r1, [sp[[SLOT]]] @ 4-byte Reload diff --git a/llvm/test/CodeGen/ARM/fast-isel-mvn.ll b/llvm/test/CodeGen/ARM/fast-isel-mvn.ll index 4f6fab02c986..886f2daa21dd 100644 --- a/llvm/test/CodeGen/ARM/fast-isel-mvn.ll +++ b/llvm/test/CodeGen/ARM/fast-isel-mvn.ll @@ -1,18 +1,14 @@ ; RUN: llc -O0 -verify-machineinstrs -fast-isel-abort -relocation-model=dynamic-no-pic -arm-use-movt=false -mtriple=armv7-apple-ios < %s | FileCheck %s --check-prefix=CHECK --check-prefix=ARM ; RUN: llc -O0 -verify-machineinstrs -fast-isel-abort -relocation-model=dynamic-no-pic -arm-use-movt=false -mtriple=armv7-linux-gnueabi < %s | FileCheck %s --check-prefix=CHECK --check-prefix=ARM -; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort -relocation-model=dynamic-no-pic -mtriple=thumbv7-apple-ios | FileCheck %s --check-prefix=THUMB -; RUN: llc -O0 -verify-machineinstrs -fast-isel-abort -relocation-model=dynamic-no-pic -arm-use-movt=true -mtriple=armv7-apple-ios < %s | FileCheck %s --check-prefix=MOVT +; RUN: llc -O0 -verify-machineinstrs -fast-isel-abort -relocation-model=dynamic-no-pic -arm-use-movt=false -mtriple=thumbv7-apple-ios < %s | FileCheck %s --check-prefix=CHECK --check-prefix=ARM +; RUN: llc -O0 -verify-machineinstrs -fast-isel-abort -relocation-model=dynamic-no-pic -arm-use-movt=true -mtriple=thumbv7-apple-ios < %s | FileCheck %s --check-prefix=CHECK --check-prefix=THUMB +; RUN: llc -O0 -verify-machineinstrs -fast-isel-abort -relocation-model=dynamic-no-pic -arm-use-movt=true -mtriple=armv7-apple-ios < %s | FileCheck %s --check-prefix=MOVT ; rdar://10412592 -; Note: The Thumb code is being generated by the target-independent selector. - define void @t1() nounwind { entry: -; ARM: t1 -; THUMB: t1 -; ARM: mvn r0, #0 -; THUMB: movw r0, #65535 -; THUMB: movt r0, #65535 +; CHECK-LABEL: t1 +; CHECK: mvn r0, #0 call void @foo(i32 -1) ret void } @@ -21,22 +17,16 @@ declare void @foo(i32) define void @t2() nounwind { entry: -; ARM: t2 -; THUMB: t2 -; ARM: mvn r0, #233 -; THUMB: movw r0, #65302 -; THUMB: movt r0, #65535 +; CHECK-LABEL: t2 +; CHECK: mvn r0, #233 call void @foo(i32 -234) ret void } define void @t3() nounwind { entry: -; ARM: t3 -; THUMB: t3 -; ARM: mvn r0, #256 -; THUMB: movw r0, #65279 -; THUMB: movt r0, #65535 +; CHECK-LABEL: t3 +; CHECK: mvn r0, #256 call void @foo(i32 -257) ret void } @@ -44,66 +34,51 @@ entry: ; Load from constant pool define void @t4() nounwind { entry: -; ARM: t4 -; THUMB: t4 -; ARM: ldr r0 -; THUMB: movw r0, #65278 -; THUMB: movt r0, #65535 +; ARM-LABEL: t4 +; ARM: ldr r0 +; THUMB-LABEL: t4 +; THUMB: movw r0, #65278 +; THUMB: movt r0, #65535 call void @foo(i32 -258) ret void } define void @t5() nounwind { entry: -; ARM: t5 -; THUMB: t5 -; ARM: mvn r0, #65280 -; THUMB: movs r0, #255 -; THUMB: movt r0, #65535 +; CHECK-LABEL: t5 +; CHECK: mvn r0, #65280 call void @foo(i32 -65281) ret void } define void @t6() nounwind { entry: -; ARM: t6 -; THUMB: t6 -; ARM: mvn r0, #978944 -; THUMB: movw r0, #4095 -; THUMB: movt r0, #65521 +; CHECK-LABEL: t6 +; CHECK: mvn r0, #978944 call void @foo(i32 -978945) ret void } define void @t7() nounwind { entry: -; ARM: t7 -; THUMB: t7 -; ARM: mvn r0, #267386880 -; THUMB: movw r0, #65535 -; THUMB: movt r0, #61455 +; CHECK-LABEL: t7 +; CHECK: mvn r0, #267386880 call void @foo(i32 -267386881) ret void } define void @t8() nounwind { entry: -; ARM: t8 -; THUMB: t8 -; ARM: mvn r0, #65280 -; THUMB: movs r0, #255 -; THUMB: movt r0, #65535 +; CHECK-LABEL: t8 +; CHECK: mvn r0, #65280 call void @foo(i32 -65281) ret void } define void @t9() nounwind { entry: -; ARM: t9 -; THUMB: t9 -; ARM: mvn r0, #2130706432 -; THUMB: movw r0, #65535 -; THUMB: movt r0, #33023 +; CHECK-LABEL: t9 +; CHECK: mvn r0, #2130706432 call void @foo(i32 -2130706433) ret void } diff --git a/llvm/test/CodeGen/ARM/fast-isel-select.ll b/llvm/test/CodeGen/ARM/fast-isel-select.ll index 40f88075039e..549c97e24dcd 100644 --- a/llvm/test/CodeGen/ARM/fast-isel-select.ll +++ b/llvm/test/CodeGen/ARM/fast-isel-select.ll @@ -12,7 +12,6 @@ entry: ; ARM: mov r0, r{{[1-9]}} ; THUMB: t1 ; THUMB: movs r{{[1-9]}}, #10 -; THUMB: movt r{{[1-9]}}, #0 ; THUMB: cmp r0, #0 ; THUMB: it eq ; THUMB: moveq r{{[1-9]}}, #20 @@ -59,13 +58,12 @@ entry: ; ARM: cmp r0, #0 ; ARM: mvneq r{{[1-9]}}, #0 ; ARM: mov r0, r{{[1-9]}} -; THUMB: t4 -; THUMB: movw r{{[1-9]}}, #65526 -; THUMB: movt r{{[1-9]}}, #65535 +; THUMB-LABEL: t4 +; THUMB: mvn [[REG:r[1-9]+]], #9 ; THUMB: cmp r0, #0 ; THUMB: it eq -; THUMB: mvneq r{{[1-9]}}, #0 -; THUMB: mov r0, r{{[1-9]}} +; THUMB: mvneq [[REG]], #0 +; THUMB: mov r0, [[REG]] %0 = select i1 %c, i32 -10, i32 -1 ret i32 %0 } diff --git a/llvm/test/CodeGen/ARM/fast-isel-vararg.ll b/llvm/test/CodeGen/ARM/fast-isel-vararg.ll index 0b7b0bd1c6f0..3ff2b151ab5f 100644 --- a/llvm/test/CodeGen/ARM/fast-isel-vararg.ll +++ b/llvm/test/CodeGen/ARM/fast-isel-vararg.ll @@ -29,7 +29,6 @@ entry: ; ARM: bl {{_?CallVariadic}} ; THUMB: sub sp, #32 ; THUMB: movs r0, #5 -; THUMB: movt r0, #0 ; THUMB: ldr r1, [sp, #28] ; THUMB: ldr r2, [sp, #24] ; THUMB: ldr r3, [sp, #20] diff --git a/llvm/test/CodeGen/PowerPC/fast-isel-call.ll b/llvm/test/CodeGen/PowerPC/fast-isel-call.ll index 33a8ba903e3d..223090523c4d 100644 --- a/llvm/test/CodeGen/PowerPC/fast-isel-call.ll +++ b/llvm/test/CodeGen/PowerPC/fast-isel-call.ll @@ -57,11 +57,11 @@ entry: ; ELF64: t10 %call = call i32 @bar(i8 zeroext 0, i8 zeroext -8, i8 zeroext -69, i8 zeroext 28, i8 zeroext 40, i8 zeroext -70) ; ELF64: li 3, 0 -; ELF64: li 4, 248 -; ELF64: li 5, 187 +; ELF64: li 4, -8 +; ELF64: li 5, -69 ; ELF64: li 6, 28 ; ELF64: li 7, 40 -; ELF64: li 8, 186 +; ELF64: li 8, -70 ; ELF64: rldicl 3, 3, 0, 56 ; ELF64: rldicl 4, 4, 0, 56 ; ELF64: rldicl 5, 5, 0, 56 diff --git a/llvm/test/CodeGen/X86/fast-isel-x86-64.ll b/llvm/test/CodeGen/X86/fast-isel-x86-64.ll index f7d2750b5b81..29f1f264a729 100644 --- a/llvm/test/CodeGen/X86/fast-isel-x86-64.ll +++ b/llvm/test/CodeGen/X86/fast-isel-x86-64.ll @@ -194,12 +194,10 @@ define void @test16() nounwind { br label %block2 block2: -; CHECK: movabsq $1 -; CHECK: cvtsi2sdq {{.*}} %xmm0 +; CHECK: movsd LCP{{.*}}_{{.*}}(%rip), %xmm0 ; CHECK: movb $1, %al ; CHECK: callq _test16callee -; AVX: movabsq $1 ; AVX: vmovsd LCP{{.*}}_{{.*}}(%rip), %xmm0 ; AVX: movb $1, %al ; AVX: callq _test16callee