Skip to content

Commit b6ff4dd

Browse files
mandlebugtstellar
authored andcommitted
[PowerPC] Handle FP physical register in inline asm constraint.
Do not defer to the base class when the register constraint is a physical fpr. The base class will select SPILLTOVSRRC as the register class and register allocation will fail on subtargets without VSX registers. Differential Revision: https://reviews.llvm.org/D91629 (cherry picked from commit 4e127bc)
1 parent e8a3972 commit b6ff4dd

File tree

3 files changed

+80
-10
lines changed

3 files changed

+80
-10
lines changed

llvm/lib/Target/PowerPC/PPCISelLowering.cpp

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15154,17 +15154,38 @@ PPCTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
1515415154
return std::make_pair(0U, &PPC::LRRCRegClass);
1515515155
}
1515615156

15157-
// If we name a VSX register, we can't defer to the base class because it
15158-
// will not recognize the correct register (their names will be VSL{0-31}
15159-
// and V{0-31} so they won't match). So we match them here.
15160-
if (Constraint.size() > 3 && Constraint[1] == 'v' && Constraint[2] == 's') {
15161-
int VSNum = atoi(Constraint.data() + 3);
15162-
assert(VSNum >= 0 && VSNum <= 63 &&
15163-
"Attempted to access a vsr out of range");
15164-
if (VSNum < 32)
15165-
return std::make_pair(PPC::VSL0 + VSNum, &PPC::VSRCRegClass);
15166-
return std::make_pair(PPC::V0 + VSNum - 32, &PPC::VSRCRegClass);
15157+
// Handle special cases of physical registers that are not properly handled
15158+
// by the base class.
15159+
if (Constraint[0] == '{' && Constraint[Constraint.size() - 1] == '}') {
15160+
// If we name a VSX register, we can't defer to the base class because it
15161+
// will not recognize the correct register (their names will be VSL{0-31}
15162+
// and V{0-31} so they won't match). So we match them here.
15163+
if (Constraint.size() > 3 && Constraint[1] == 'v' && Constraint[2] == 's') {
15164+
int VSNum = atoi(Constraint.data() + 3);
15165+
assert(VSNum >= 0 && VSNum <= 63 &&
15166+
"Attempted to access a vsr out of range");
15167+
if (VSNum < 32)
15168+
return std::make_pair(PPC::VSL0 + VSNum, &PPC::VSRCRegClass);
15169+
return std::make_pair(PPC::V0 + VSNum - 32, &PPC::VSRCRegClass);
15170+
}
15171+
15172+
// For float registers, we can't defer to the base class as it will match
15173+
// the SPILLTOVSRRC class.
15174+
if (Constraint.size() > 3 && Constraint[1] == 'f') {
15175+
int RegNum = atoi(Constraint.data() + 2);
15176+
if (RegNum > 31 || RegNum < 0)
15177+
report_fatal_error("Invalid floating point register number");
15178+
if (VT == MVT::f32 || VT == MVT::i32)
15179+
return Subtarget.hasSPE()
15180+
? std::make_pair(PPC::R0 + RegNum, &PPC::GPRCRegClass)
15181+
: std::make_pair(PPC::F0 + RegNum, &PPC::F4RCRegClass);
15182+
if (VT == MVT::f64 || VT == MVT::i64)
15183+
return Subtarget.hasSPE()
15184+
? std::make_pair(PPC::S0 + RegNum, &PPC::SPERCRegClass)
15185+
: std::make_pair(PPC::F0 + RegNum, &PPC::F8RCRegClass);
15186+
}
1516715187
}
15188+
1516815189
std::pair<unsigned, const TargetRegisterClass *> R =
1516915190
TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT);
1517015191

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
; RUN: llc -verify-machineinstrs < %s -mtriple=powerpc-unknown-linux-gnu \
2+
; RUN: -mattr=+spe | FileCheck %s
3+
4+
define i32 @test_f32(float %x) {
5+
; CHECK-LABEL: test_f32:
6+
; CHECK: #APP
7+
; CHECK-NEXT: efsctsi 31, 3
8+
; CHECK-NEXT: #NO_APP
9+
entry:
10+
%0 = call i32 asm sideeffect "efsctsi $0, $1", "={f31},f"(float %x)
11+
ret i32 %0
12+
}
13+
14+
define i32 @test_f64(double %x) {
15+
; CHECK-LABEL: test_f64:
16+
; CHECK: #APP
17+
; CHECK-NEXT: efdctsi 0, 3
18+
; CHECK-NEXT: #NO_APP
19+
entry:
20+
%0 = call i32 asm sideeffect "efdctsi $0, $1", "={f0},d"(double %x)
21+
ret i32 %0
22+
}
23+
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
; RUN: llc -mcpu=pwr7 -mattr=-altivec -verify-machineinstrs \
2+
; RUN: -mtriple=powerpc-unknown-aix < %s | FileCheck %s
3+
4+
; RUN: llc -mcpu=pwr7 -mattr=-altivec -verify-machineinstrs \
5+
; RUN: -mtriple=powerpc64-unknown-aix < %s | FileCheck %s
6+
7+
8+
define dso_local double @test_double(double %a, double %b) {
9+
entry:
10+
%0 = tail call double asm "fadd. $0,$1,$2\0A", "={f31},d,d,0"(double %a, double %b, double 0.000000e+00)
11+
ret double %0
12+
}
13+
14+
; CHECK-LABEL: test_double
15+
; CHECK: #APP
16+
; CHECK-NEXT: fadd. 31,1,2
17+
18+
define dso_local signext i32 @test_int(double %a, double %b) {
19+
entry:
20+
%0 = tail call i32 asm "fadd. $0,$1,$2\0A", "={f0},d,d,0"(double %a, double %b, i32 0)
21+
ret i32 %0
22+
}
23+
24+
; CHECK-LABEL: test_int
25+
; CHECK: #APP
26+
; CHECK-NEXT: fadd. 0,1,2

0 commit comments

Comments
 (0)