summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/patches/patch-r262261-llvm-r199187-sparc.diff
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/patches/patch-r262261-llvm-r199187-sparc.diff')
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r199187-sparc.diff81
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);
OpenPOWER on IntegriCloud