diff options
Diffstat (limited to 'contrib/llvm/patches/patch-r262261-llvm-r199187-sparc.diff')
-rw-r--r-- | contrib/llvm/patches/patch-r262261-llvm-r199187-sparc.diff | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r199187-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r199187-sparc.diff new file mode 100644 index 0000000..bfc1cfc --- /dev/null +++ b/contrib/llvm/patches/patch-r262261-llvm-r199187-sparc.diff @@ -0,0 +1,81 @@ +Pull in r199187 from upstream llvm trunk (by Jakob Stoklund Olesen): + + Always let value types influence register classes. + + When creating a virtual register for a def, the value type should be + used to pick the register class. If we only use the register class + constraint on the instruction, we might pick a too large register class. + + Some registers can store values of different sizes. For example, the x86 + xmm registers can hold f32, f64, and 128-bit vectors. The three + different value sizes are represented by register classes with identical + register sets: FR32, FR64, and VR128. These register classes have + different spill slot sizes, so it is important to use the right one. + + The register class constraint on an instruction doesn't necessarily care + about the size of the value its defining. The value type determines + that. + + This fixes a problem where InstrEmitter was picking 32-bit register + classes for 64-bit values on SPARC. + +Introduced here: http://svn.freebsd.org/changeset/base/262261 + +Index: test/CodeGen/SPARC/spillsize.ll +=================================================================== +--- test/CodeGen/SPARC/spillsize.ll ++++ test/CodeGen/SPARC/spillsize.ll +@@ -0,0 +1,25 @@ ++; RUN: llc < %s -verify-machineinstrs | FileCheck %s ++target datalayout = "E-m:e-i64:64-n32:64-S128" ++target triple = "sparcv9" ++ ++; CHECK-LABEL: spill4 ++; This function spills two values: %p and the materialized large constant. ++; Both must use 8-byte spill and fill instructions. ++; CHECK: stx %{{..}}, [%fp+ ++; CHECK: stx %{{..}}, [%fp+ ++; CHECK: ldx [%fp+ ++; CHECK: ldx [%fp+ ++define void @spill4(i64* nocapture %p) { ++entry: ++ %val0 = load i64* %p ++ %cmp0 = icmp ult i64 %val0, 385672958347594845 ++ %cm80 = zext i1 %cmp0 to i64 ++ store i64 %cm80, i64* %p, align 8 ++ tail call void asm sideeffect "", "~{i0},~{i1},~{i2},~{i3},~{i4},~{i5},~{g2},~{g3},~{g4},~{g5},~{l0},~{l1},~{l2},~{l3},~{l4},~{l5},~{l6},~{l7},~{o0},~{o1},~{o2},~{o3},~{o4},~{o5},~{o7}"() ++ %arrayidx1 = getelementptr inbounds i64* %p, i64 1 ++ %val = load i64* %arrayidx1 ++ %cmp = icmp ult i64 %val, 385672958347594845 ++ %cm8 = select i1 %cmp, i64 10, i64 20 ++ store i64 %cm8, i64* %arrayidx1, align 8 ++ ret void ++} +Index: lib/CodeGen/SelectionDAG/InstrEmitter.cpp +=================================================================== +--- lib/CodeGen/SelectionDAG/InstrEmitter.cpp ++++ lib/CodeGen/SelectionDAG/InstrEmitter.cpp +@@ -220,10 +220,19 @@ void InstrEmitter::CreateVirtualRegisters(SDNode * + unsigned VRBase = 0; + const TargetRegisterClass *RC = + TRI->getAllocatableClass(TII->getRegClass(II, i, TRI, *MF)); +- // If the register class is unknown for the given definition, then try to +- // infer one from the value type. +- if (!RC && i < NumResults) +- RC = TLI->getRegClassFor(Node->getSimpleValueType(i)); ++ // Always let the value type influence the used register class. The ++ // constraints on the instruction may be too lax to represent the value ++ // type correctly. For example, a 64-bit float (X86::FR64) can't live in ++ // the 32-bit float super-class (X86::FR32). ++ if (i < NumResults && TLI->isTypeLegal(Node->getSimpleValueType(i))) { ++ const TargetRegisterClass *VTRC = ++ TLI->getRegClassFor(Node->getSimpleValueType(i)); ++ if (RC) ++ VTRC = TRI->getCommonSubClass(RC, VTRC); ++ if (VTRC) ++ RC = VTRC; ++ } ++ + if (II.OpInfo[i].isOptionalDef()) { + // Optional def must be a physical register. + unsigned NumResults = CountResults(Node); |