[PowerPC] Don't use a non-allocatable register to implement the 'cc' alias

GCC accepts 'cc' as an alias for 'cr0', and we need to do the same when
processing inline asm constraints. This had previously been implemented using a
non-allocatable register, named 'cc', that was listed as an alias of 'cr0', but
the infrastructure does not seem to support this properly (neither the register
allocator nor the scheduler properly accounts for the alias). Instead, we can
just process this as a naming alias inside of the inline asm
constraint-processing code, so we'll do that instead.

There are two regression tests, one where the post-RA scheduler did the wrong
thing with the non-allocatable alias, and one where the register allocator did
the wrong thing. Fixes PR21742.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@223708 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Hal Finkel 2014-12-08 22:54:22 +00:00
parent 7ec769c971
commit b849e04d2b
4 changed files with 349 additions and 9 deletions

View File

@ -8959,6 +8959,12 @@ PPCTargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint,
&PPC::G8RCRegClass);
}
// GCC accepts 'cc' as an alias for 'cr0', and we need to do the same.
if (!R.second && StringRef("{cc}").equals_lower(Constraint)) {
R.first = PPC::CR0;
R.second = &PPC::CRRCRegClass;
}
return R;
}

View File

@ -188,11 +188,6 @@ def CR6 : CR<6, "cr6", [CR6LT, CR6GT, CR6EQ, CR6UN]>, DwarfRegNum<[74, 74]>;
def CR7 : CR<7, "cr7", [CR7LT, CR7GT, CR7EQ, CR7UN]>, DwarfRegNum<[75, 75]>;
}
// An alias for "cr0" used by GCC.
def CC : PPCReg<"cc">, DwarfRegAlias<CR0> {
let Aliases = [CR0];
}
// Link register
def LR : SPR<8, "lr">, DwarfRegNum<[-2, 65]>;
//let Aliases = [LR] in
@ -306,7 +301,3 @@ def CARRYRC : RegisterClass<"PPC", [i32], 32, (add CARRY)> {
let CopyCost = -1;
}
def CCRC : RegisterClass<"PPC", [i32], 32, (add CC)> {
let isAllocatable = 0;
}

View File

@ -0,0 +1,175 @@
; RUN: llc -mcpu=pwr7 < %s | FileCheck %s
target datalayout = "E-m:e-i64:64-n32:64"
target triple = "powerpc64-unknown-linux-gnu"
; Function Attrs: nounwind
define void @jbd2_journal_commit_transaction() #0 {
entry:
br i1 undef, label %do.body, label %if.then5
if.then5: ; preds = %entry
unreachable
do.body: ; preds = %entry
br i1 undef, label %do.body.i, label %trace_jbd2_start_commit.exit
do.body.i: ; preds = %do.body
unreachable
trace_jbd2_start_commit.exit: ; preds = %do.body
br i1 undef, label %do.body.i1116, label %trace_jbd2_commit_locking.exit
do.body.i1116: ; preds = %trace_jbd2_start_commit.exit
unreachable
trace_jbd2_commit_locking.exit: ; preds = %trace_jbd2_start_commit.exit
br i1 undef, label %while.end, label %while.body.lr.ph
while.body.lr.ph: ; preds = %trace_jbd2_commit_locking.exit
unreachable
while.end: ; preds = %trace_jbd2_commit_locking.exit
br i1 undef, label %spin_unlock.exit1146, label %if.then.i.i.i.i1144
if.then.i.i.i.i1144: ; preds = %while.end
unreachable
spin_unlock.exit1146: ; preds = %while.end
br i1 undef, label %spin_unlock.exit1154, label %if.then.i.i.i.i1152
if.then.i.i.i.i1152: ; preds = %spin_unlock.exit1146
unreachable
spin_unlock.exit1154: ; preds = %spin_unlock.exit1146
br i1 undef, label %do.body.i1159, label %trace_jbd2_commit_flushing.exit
do.body.i1159: ; preds = %spin_unlock.exit1154
br i1 undef, label %if.end.i1166, label %do.body5.i1165
do.body5.i1165: ; preds = %do.body.i1159
unreachable
if.end.i1166: ; preds = %do.body.i1159
unreachable
trace_jbd2_commit_flushing.exit: ; preds = %spin_unlock.exit1154
br i1 undef, label %for.end.i, label %for.body.lr.ph.i
for.body.lr.ph.i: ; preds = %trace_jbd2_commit_flushing.exit
unreachable
for.end.i: ; preds = %trace_jbd2_commit_flushing.exit
br i1 undef, label %journal_submit_data_buffers.exit, label %if.then.i.i.i.i31.i
if.then.i.i.i.i31.i: ; preds = %for.end.i
br label %journal_submit_data_buffers.exit
journal_submit_data_buffers.exit: ; preds = %if.then.i.i.i.i31.i, %for.end.i
br i1 undef, label %if.end103, label %if.then102
if.then102: ; preds = %journal_submit_data_buffers.exit
unreachable
if.end103: ; preds = %journal_submit_data_buffers.exit
br i1 undef, label %do.body.i1182, label %trace_jbd2_commit_logging.exit
do.body.i1182: ; preds = %if.end103
br i1 undef, label %if.end.i1189, label %do.body5.i1188
do.body5.i1188: ; preds = %do.body5.i1188, %do.body.i1182
br i1 undef, label %if.end.i1189, label %do.body5.i1188
if.end.i1189: ; preds = %do.body5.i1188, %do.body.i1182
unreachable
trace_jbd2_commit_logging.exit: ; preds = %if.end103
br label %while.cond129.outer1451
while.cond129.outer1451: ; preds = %start_journal_io, %trace_jbd2_commit_logging.exit
br label %while.cond129
while.cond129: ; preds = %if.then135, %while.cond129.outer1451
br i1 undef, label %while.end246, label %if.then135
if.then135: ; preds = %while.cond129
br i1 undef, label %start_journal_io, label %while.cond129
start_journal_io: ; preds = %if.then135
br label %while.cond129.outer1451
while.end246: ; preds = %while.cond129
br i1 undef, label %for.end.i1287, label %for.body.i1277
for.body.i1277: ; preds = %while.end246
unreachable
for.end.i1287: ; preds = %while.end246
br i1 undef, label %journal_finish_inode_data_buffers.exit, label %if.then.i.i.i.i84.i
if.then.i.i.i.i84.i: ; preds = %for.end.i1287
unreachable
journal_finish_inode_data_buffers.exit: ; preds = %for.end.i1287
br i1 undef, label %if.end256, label %if.then249
if.then249: ; preds = %journal_finish_inode_data_buffers.exit
unreachable
if.end256: ; preds = %journal_finish_inode_data_buffers.exit
br label %while.body318
while.body318: ; preds = %wait_on_buffer.exit, %if.end256
br i1 undef, label %wait_on_buffer.exit, label %if.then.i1296
if.then.i1296: ; preds = %while.body318
br label %wait_on_buffer.exit
wait_on_buffer.exit: ; preds = %if.then.i1296, %while.body318
br i1 undef, label %do.body378, label %while.body318
do.body378: ; preds = %wait_on_buffer.exit
br i1 undef, label %while.end418, label %while.body392.lr.ph
while.body392.lr.ph: ; preds = %do.body378
br label %while.body392
while.body392: ; preds = %wait_on_buffer.exit1319, %while.body392.lr.ph
%0 = load i8** undef, align 8
%add.ptr399 = getelementptr inbounds i8* %0, i64 -72
%b_state.i.i1314 = bitcast i8* %add.ptr399 to i64*
%tobool.i1316 = icmp eq i64 undef, 0
br i1 %tobool.i1316, label %wait_on_buffer.exit1319, label %if.then.i1317
if.then.i1317: ; preds = %while.body392
unreachable
wait_on_buffer.exit1319: ; preds = %while.body392
%1 = load volatile i64* %b_state.i.i1314, align 8
%conv.i.i1322 = and i64 %1, 1
%lnot404 = icmp eq i64 %conv.i.i1322, 0
%.err.4 = select i1 %lnot404, i32 -5, i32 undef
%2 = call i64 asm sideeffect "1:.long 0x7c0000a8 $| ((($0) & 0x1f) << 21) $| (((0) & 0x1f) << 16) $| ((($3) & 0x1f) << 11) $| (((0) & 0x1) << 0) \0Aandc $0,$0,$2\0Astdcx. $0,0,$3\0Abne- 1b\0A", "=&r,=*m,r,r,*m,~{cc},~{memory}"(i64* %b_state.i.i1314, i64 262144, i64* %b_state.i.i1314, i64* %b_state.i.i1314) #0
store i8* %0, i8** undef, align 8
%cmp.i1312 = icmp eq i32* undef, undef
br i1 %cmp.i1312, label %while.end418, label %while.body392
while.end418: ; preds = %wait_on_buffer.exit1319, %do.body378
%err.4.lcssa = phi i32 [ undef, %do.body378 ], [ %.err.4, %wait_on_buffer.exit1319 ]
%tobool419 = icmp eq i32 %err.4.lcssa, 0
br i1 %tobool419, label %if.end421, label %if.then420
; CHECK-LABEL: @jbd2_journal_commit_transaction
; CHECK: andi.
; CHECK: cror [[REG:[0-9]+]], 1, 1
; CHECK: stdcx.
; CHECK: isel {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}, [[REG]]
if.then420: ; preds = %while.end418
unreachable
if.end421: ; preds = %while.end418
unreachable
}
attributes #0 = { nounwind }

View File

@ -0,0 +1,168 @@
; RUN: llc -mcpu=pwr7 < %s | FileCheck %s
target datalayout = "E-m:e-i64:64-n32:64"
target triple = "powerpc64-unknown-linux-gnu"
; Function Attrs: nounwind
define void @jbd2_journal_commit_transaction(i32* %journal) #0 {
entry:
br i1 undef, label %do.body, label %if.then5
if.then5: ; preds = %entry
unreachable
do.body: ; preds = %entry
br i1 undef, label %do.body.i, label %trace_jbd2_start_commit.exit
do.body.i: ; preds = %do.body
unreachable
trace_jbd2_start_commit.exit: ; preds = %do.body
br i1 undef, label %do.body.i1116, label %trace_jbd2_commit_locking.exit
do.body.i1116: ; preds = %trace_jbd2_start_commit.exit
br i1 undef, label %if.end.i1123, label %do.body5.i1122
do.body5.i1122: ; preds = %do.body.i1116
unreachable
if.end.i1123: ; preds = %do.body.i1116
br label %trace_jbd2_commit_locking.exit
trace_jbd2_commit_locking.exit: ; preds = %if.end.i1123, %trace_jbd2_start_commit.exit
br i1 undef, label %spin_unlock.exit1146, label %if.then.i.i.i.i1144
if.then.i.i.i.i1144: ; preds = %trace_jbd2_commit_locking.exit
unreachable
spin_unlock.exit1146: ; preds = %trace_jbd2_commit_locking.exit
br i1 undef, label %spin_unlock.exit1154, label %if.then.i.i.i.i1152
if.then.i.i.i.i1152: ; preds = %spin_unlock.exit1146
br label %spin_unlock.exit1154
spin_unlock.exit1154: ; preds = %if.then.i.i.i.i1152, %spin_unlock.exit1146
br i1 undef, label %do.body.i1159, label %trace_jbd2_commit_flushing.exit
do.body.i1159: ; preds = %spin_unlock.exit1154
unreachable
trace_jbd2_commit_flushing.exit: ; preds = %spin_unlock.exit1154
br i1 undef, label %for.end.i, label %for.body.lr.ph.i
for.body.lr.ph.i: ; preds = %trace_jbd2_commit_flushing.exit
br i1 undef, label %spin_unlock.exit.i, label %if.then.i.i.i.i.i
if.then.i.i.i.i.i: ; preds = %for.body.lr.ph.i
unreachable
spin_unlock.exit.i: ; preds = %for.body.lr.ph.i
unreachable
for.end.i: ; preds = %trace_jbd2_commit_flushing.exit
br i1 undef, label %journal_submit_data_buffers.exit, label %if.then.i.i.i.i31.i
if.then.i.i.i.i31.i: ; preds = %for.end.i
unreachable
journal_submit_data_buffers.exit: ; preds = %for.end.i
br i1 undef, label %if.end103, label %if.then102
if.then102: ; preds = %journal_submit_data_buffers.exit
unreachable
if.end103: ; preds = %journal_submit_data_buffers.exit
br i1 undef, label %do.body.i1182, label %trace_jbd2_commit_logging.exit
do.body.i1182: ; preds = %if.end103
unreachable
trace_jbd2_commit_logging.exit: ; preds = %if.end103
br i1 undef, label %for.end.i1287, label %for.body.i1277
for.body.i1277: ; preds = %trace_jbd2_commit_logging.exit
unreachable
for.end.i1287: ; preds = %trace_jbd2_commit_logging.exit
br i1 undef, label %journal_finish_inode_data_buffers.exit, label %if.then.i.i.i.i84.i
if.then.i.i.i.i84.i: ; preds = %for.end.i1287
unreachable
journal_finish_inode_data_buffers.exit: ; preds = %for.end.i1287
br i1 undef, label %if.end256, label %if.then249
if.then249: ; preds = %journal_finish_inode_data_buffers.exit
unreachable
if.end256: ; preds = %journal_finish_inode_data_buffers.exit
br i1 undef, label %do.body277, label %if.then260
if.then260: ; preds = %if.end256
br label %do.body277
do.body277: ; preds = %if.then260, %if.end256
br label %while.body318
while.body318: ; preds = %wait_on_buffer.exit, %do.body277
%tobool.i1295 = icmp eq i64 undef, 0
br i1 %tobool.i1295, label %wait_on_buffer.exit, label %if.then.i1296
if.then.i1296: ; preds = %while.body318
unreachable
wait_on_buffer.exit: ; preds = %while.body318
br i1 undef, label %do.body378, label %while.body318
do.body378: ; preds = %wait_on_buffer.exit
br i1 undef, label %while.end418, label %while.body392.lr.ph
while.body392.lr.ph: ; preds = %do.body378
br label %while.body392
while.body392: ; preds = %wait_on_buffer.exit1319, %while.body392.lr.ph
%0 = load i8** undef, align 8
%add.ptr399 = getelementptr inbounds i8* %0, i64 -72
%b_state.i.i1314 = bitcast i8* %add.ptr399 to i64*
%tobool.i1316 = icmp eq i64 undef, 0
br i1 %tobool.i1316, label %wait_on_buffer.exit1319, label %if.then.i1317
if.then.i1317: ; preds = %while.body392
unreachable
wait_on_buffer.exit1319: ; preds = %while.body392
%1 = load volatile i64* %b_state.i.i1314, align 8
%conv.i.i1322 = and i64 %1, 1
%lnot404 = icmp eq i64 %conv.i.i1322, 0
%.err.4 = select i1 %lnot404, i32 -5, i32 undef
%2 = call i64 asm sideeffect "1:.long 0x7c0000a8 $| ((($0) & 0x1f) << 21) $| (((0) & 0x1f) << 16) $| ((($3) & 0x1f) << 11) $| (((0) & 0x1) << 0) \0Aandc $0,$0,$2\0Astdcx. $0,0,$3\0Abne- 1b\0A", "=&r,=*m,r,r,*m,~{cc},~{memory}"(i64* %b_state.i.i1314, i64 262144, i64* %b_state.i.i1314, i64* %b_state.i.i1314) #1
%prev.i.i.i1325 = getelementptr inbounds i8* %0, i64 8
%3 = load i32** null, align 8
store i32* %3, i32** undef, align 8
call void @__brelse(i32* undef) #1
br i1 undef, label %while.end418, label %while.body392
; CHECK-LABEL: @jbd2_journal_commit_transaction
; CHECK: andi.
; CHECK: cror [[REG:[0-9]+]], 1, 1
; CHECK: stdcx.
; CHECK: isel {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}, [[REG]]
while.end418: ; preds = %wait_on_buffer.exit1319, %do.body378
%err.4.lcssa = phi i32 [ undef, %do.body378 ], [ %.err.4, %wait_on_buffer.exit1319 ]
br i1 undef, label %if.end421, label %if.then420
if.then420: ; preds = %while.end418
call void @jbd2_journal_abort(i32* %journal, i32 signext %err.4.lcssa) #1
br label %if.end421
if.end421: ; preds = %if.then420, %while.end418
unreachable
}
declare void @jbd2_journal_abort(i32*, i32 signext)
declare void @__brelse(i32*)
attributes #0 = { nounwind }
attributes #1 = { nounwind }