OSDN Git Service

[PowerPC] Don't use a non-allocatable register to implement the 'cc' alias
authorHal Finkel <hfinkel@anl.gov>
Mon, 8 Dec 2014 22:54:22 +0000 (22:54 +0000)
committerHal Finkel <hfinkel@anl.gov>
Mon, 8 Dec 2014 22:54:22 +0000 (22:54 +0000)
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

lib/Target/PowerPC/PPCISelLowering.cpp
lib/Target/PowerPC/PPCRegisterInfo.td
test/CodeGen/PowerPC/subreg-postra-2.ll [new file with mode: 0644]
test/CodeGen/PowerPC/subreg-postra.ll [new file with mode: 0644]

index 10e4e60..0bc10a1 100644 (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;
 }
 
index e928858..0442a94 100644 (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;
-}
-
diff --git a/test/CodeGen/PowerPC/subreg-postra-2.ll b/test/CodeGen/PowerPC/subreg-postra-2.ll
new file mode 100644 (file)
index 0000000..2faaa61
--- /dev/null
@@ -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 }
+
diff --git a/test/CodeGen/PowerPC/subreg-postra.ll b/test/CodeGen/PowerPC/subreg-postra.ll
new file mode 100644 (file)
index 0000000..b10fa66
--- /dev/null
@@ -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 }
+