<div dir="ltr"><div dir="ltr">I suspect that this caused the following build error in Chromium:</div><div dir="ltr"><br><div><div>fatal error: error in backend: Error while trying to spill R0 from class GPR: Cannot scavenge register without an emergency spill slot!</div><div>clang: error: clang frontend command failed with exit code 70 (use -v to see invocation)</div><div>clang version 9.0.0 (trunk 351951)</div><div>Target: arm-unknown-linux-android</div><div>Thread model: posix</div><div>InstalledDir: ../../third_party/llvm-build/Release+Asserts/bin</div><div>clang: note: diagnostic msg: PLEASE submit a bug report to <a href="https://bugs.llvm.org/">https://bugs.llvm.org/</a> and include the crash backtrace, preprocessed source, and associated run script.</div><div>clang: note: diagnostic msg:</div><div>********************</div><div><br></div><div>PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:</div><div>Preprocessed source(s) and associated run script(s) are located at:</div><div>clang: note: diagnostic msg: /b/s/w/ir/tmp/t/idct8x8_add_neon-ce36a6.c</div><div>clang: note: diagnostic msg: /b/s/w/ir/tmp/t/idct8x8_add_neon-ce36a6.sh</div></div><div><br></div><div>I'll get the reproducer, and I'll revert this change if I can confirm that it caused the regression.</div><div></div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Jan 23, 2019 at 2:18 AM David Green via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Author: dmgreen<br>
Date: Wed Jan 23 02:18:30 2019<br>
New Revision: 351938<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=351938&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=351938&view=rev</a><br>
Log:<br>
[ARM] Alter the register allocation order for minsize on Thumb2<br>
<br>
Currently in Arm code, we allocate LR first, under the assumption that<br>
it needs to be saved anyway. Unfortunately this has the disadvantage<br>
that it will require any instructions using it to be the longer thumb2<br>
instructions, not the shorter thumb1 ones.<br>
<br>
This switches the order when we are optimising for minsize, returning to<br>
the default order so that more lower registers can be used. It can end<br>
up requiring more pushed registers, but on average produces smaller code.<br>
<br>
Differential Revision: <a href="https://reviews.llvm.org/D56008" rel="noreferrer" target="_blank">https://reviews.llvm.org/D56008</a><br>
<br>
Added:<br>
    llvm/trunk/test/CodeGen/Thumb2/reg-order.ll<br>
Modified:<br>
    llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td<br>
<br>
Modified: llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td?rev=351938&r1=351937&r2=351938&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td?rev=351938&r1=351937&r2=351938&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td (original)<br>
+++ llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td Wed Jan 23 02:18:30 2019<br>
@@ -204,13 +204,21 @@ def FPINST2 : ARMReg<10, "fpinst2">;<br>
 def GPR : RegisterClass<"ARM", [i32], 32, (add (sequence "R%u", 0, 12),<br>
                                                SP, LR, PC)> {<br>
   // Allocate LR as the first CSR since it is always saved anyway.<br>
+  // For Thumb2, using LR would force 32bit Thumb2 instructions, not the smaller<br>
+  // Thumb1 ones. It is a little better for codesize on average to use the<br>
+  // default order.<br>
   // For Thumb1 mode, we don't want to allocate hi regs at all, as we don't<br>
   // know how to spill them. If we make our prologue/epilogue code smarter at<br>
   // some point, we can go back to using the above allocation orders for the<br>
   // Thumb1 instructions that know how to use hi regs.<br>
   let AltOrders = [(add LR, GPR), (trunc GPR, 8)];<br>
   let AltOrderSelect = [{<br>
-      return 1 + MF.getSubtarget<ARMSubtarget>().isThumb1Only();<br>
+      if (MF.getSubtarget<ARMSubtarget>().isThumb1Only())<br>
+        return 2;<br>
+      if (MF.getSubtarget<ARMSubtarget>().isThumb2() &&<br>
+          MF.getFunction().optForMinSize())<br>
+        return 0;<br>
+      return 1;<br>
   }];<br>
   let DiagnosticString = "operand must be a register in range [r0, r15]";<br>
 }<br>
@@ -221,7 +229,12 @@ def GPR : RegisterClass<"ARM", [i32], 32<br>
 def GPRnopc : RegisterClass<"ARM", [i32], 32, (sub GPR, PC)> {<br>
   let AltOrders = [(add LR, GPRnopc), (trunc GPRnopc, 8)];<br>
   let AltOrderSelect = [{<br>
-      return 1 + MF.getSubtarget<ARMSubtarget>().isThumb1Only();<br>
+      if (MF.getSubtarget<ARMSubtarget>().isThumb1Only())<br>
+        return 2;<br>
+      if (MF.getSubtarget<ARMSubtarget>().isThumb2() &&<br>
+          MF.getFunction().optForMinSize())<br>
+        return 0;<br>
+      return 1;<br>
   }];<br>
   let DiagnosticString = "operand must be a register in range [r0, r14]";<br>
 }<br>
@@ -232,7 +245,12 @@ def GPRnopc : RegisterClass<"ARM", [i32]<br>
 def GPRwithAPSR : RegisterClass<"ARM", [i32], 32, (add (sub GPR, PC), APSR_NZCV)> {<br>
   let AltOrders = [(add LR, GPRnopc), (trunc GPRnopc, 8)];<br>
   let AltOrderSelect = [{<br>
-      return 1 + MF.getSubtarget<ARMSubtarget>().isThumb1Only();<br>
+      if (MF.getSubtarget<ARMSubtarget>().isThumb1Only())<br>
+        return 2;<br>
+      if (MF.getSubtarget<ARMSubtarget>().isThumb2() &&<br>
+          MF.getFunction().optForMinSize())<br>
+        return 0;<br>
+      return 1;<br>
   }];<br>
   let DiagnosticString = "operand must be a register in range [r0, r14] or apsr_nzcv";<br>
 }<br>
@@ -253,7 +271,12 @@ def GPRsp : RegisterClass<"ARM", [i32],<br>
 def rGPR : RegisterClass<"ARM", [i32], 32, (sub GPR, SP, PC)> {<br>
   let AltOrders = [(add LR, rGPR), (trunc rGPR, 8)];<br>
   let AltOrderSelect = [{<br>
-      return 1 + MF.getSubtarget<ARMSubtarget>().isThumb1Only();<br>
+      if (MF.getSubtarget<ARMSubtarget>().isThumb1Only())<br>
+        return 2;<br>
+      if (MF.getSubtarget<ARMSubtarget>().isThumb2() &&<br>
+          MF.getFunction().optForMinSize())<br>
+        return 0;<br>
+      return 1;<br>
   }];<br>
   let DiagnosticType = "rGPR";<br>
 }<br>
<br>
Added: llvm/trunk/test/CodeGen/Thumb2/reg-order.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Thumb2/reg-order.ll?rev=351938&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Thumb2/reg-order.ll?rev=351938&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/Thumb2/reg-order.ll (added)<br>
+++ llvm/trunk/test/CodeGen/Thumb2/reg-order.ll Wed Jan 23 02:18:30 2019<br>
@@ -0,0 +1,106 @@<br>
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py<br>
+; RUN: llc < %s -mtriple=thumbv7m-none-eabi | FileCheck %s<br>
+<br>
+<br>
+define i32 @test(i32 %a, i32 %b, i32 %c, i32 %d) #0 {<br>
+; CHECK-LABEL: test:<br>
+; CHECK:       @ %bb.0: @ %entry<br>
+; CHECK-NEXT:    .save {r4, lr}<br>
+; CHECK-NEXT:    push {r4, lr}<br>
+; CHECK-NEXT:    adds r4, r3, r0<br>
+; CHECK-NEXT:    add.w r12, r2, r1<br>
+; CHECK-NEXT:    add r0, r1<br>
+; CHECK-NEXT:    adds r1, r3, r2<br>
+; CHECK-NEXT:    mul r4, r4, r12<br>
+; CHECK-NEXT:    mla r0, r1, r0, r4<br>
+; CHECK-NEXT:    pop {r4, pc}<br>
+entry:<br>
+  %add = add nsw i32 %b, %a<br>
+  %add1 = add nsw i32 %d, %c<br>
+  %mul = mul nsw i32 %add1, %add<br>
+  %add2 = add nsw i32 %d, %a<br>
+  %add3 = add nsw i32 %c, %b<br>
+  %mul4 = mul nsw i32 %add2, %add3<br>
+  %add5 = add nsw i32 %mul, %mul4<br>
+  ret i32 %add5<br>
+}<br>
+<br>
+define void @loop(i32 %I, i8* %A, i8* %B) #0 {<br>
+; CHECK-LABEL: loop:<br>
+; CHECK:       @ %bb.0: @ %entry<br>
+; CHECK-NEXT:    .save {r4, r5, r6, r7, lr}<br>
+; CHECK-NEXT:    push {r4, r5, r6, r7, lr}<br>
+; CHECK-NEXT:    mov.w r12, #0<br>
+; CHECK-NEXT:    b .LBB1_2<br>
+; CHECK-NEXT:  .LBB1_1: @ %for.body<br>
+; CHECK-NEXT:    @ in Loop: Header=BB1_2 Depth=1<br>
+; CHECK-NEXT:    add.w r4, r12, r12, lsl #1<br>
+; CHECK-NEXT:    add.w r3, r2, r12, lsl #2<br>
+; CHECK-NEXT:    add r4, r1<br>
+; CHECK-NEXT:    add.w r12, r12, #1<br>
+; CHECK-NEXT:    ldrsb.w r6, [r4, #2]<br>
+; CHECK-NEXT:    ldrsb.w r5, [r4]<br>
+; CHECK-NEXT:    mov r7, r6<br>
+; CHECK-NEXT:    cmp r5, r6<br>
+; CHECK-NEXT:    it gt<br>
+; CHECK-NEXT:    movgt r7, r5<br>
+; CHECK-NEXT:    ldrsb.w r4, [r4, #1]<br>
+; CHECK-NEXT:    cmp r7, r4<br>
+; CHECK-NEXT:    it le<br>
+; CHECK-NEXT:    movle r7, r4<br>
+; CHECK-NEXT:    subs r4, r7, r4<br>
+; CHECK-NEXT:    subs r6, r7, r6<br>
+; CHECK-NEXT:    strb r6, [r3, #3]<br>
+; CHECK-NEXT:    strb r4, [r3, #2]<br>
+; CHECK-NEXT:    subs r4, r7, r5<br>
+; CHECK-NEXT:    strb r4, [r3, #1]<br>
+; CHECK-NEXT:    mvns r4, r7<br>
+; CHECK-NEXT:    strb r4, [r3]<br>
+; CHECK-NEXT:  .LBB1_2: @ %for.cond<br>
+; CHECK-NEXT:    @ =>This Inner Loop Header: Depth=1<br>
+; CHECK-NEXT:    cmp r12, r0<br>
+; CHECK-NEXT:    blt .LBB1_1<br>
+; CHECK-NEXT:  @ %bb.3: @ %for.cond.cleanup<br>
+; CHECK-NEXT:    pop {r4, r5, r6, r7, pc}<br>
+entry:<br>
+  br label %for.cond<br>
+<br>
+for.cond:                                         ; preds = %for.body, %entry<br>
+  %A.addr.0 = phi i8* [ %A, %entry ], [ %incdec.ptr2, %for.body ]<br>
+  %B.addr.0 = phi i8* [ %B, %entry ], [ %incdec.ptr47, %for.body ]<br>
+  %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ]<br>
+  %cmp = icmp slt i32 %i.0, %I<br>
+  br i1 %cmp, label %for.body, label %for.cond.cleanup<br>
+<br>
+for.body:                                         ; preds = %for.cond<br>
+  %incdec.ptr = getelementptr inbounds i8, i8* %A.addr.0, i32 1<br>
+  %0 = load i8, i8* %A.addr.0, align 1<br>
+  %incdec.ptr1 = getelementptr inbounds i8, i8* %A.addr.0, i32 2<br>
+  %1 = load i8, i8* %incdec.ptr, align 1<br>
+  %incdec.ptr2 = getelementptr inbounds i8, i8* %A.addr.0, i32 3<br>
+  %2 = load i8, i8* %incdec.ptr1, align 1<br>
+  %3 = icmp sgt i8 %0, %2<br>
+  %4 = select i1 %3, i8 %0, i8 %2<br>
+  %5 = icmp sgt i8 %4, %1<br>
+  %6 = select i1 %5, i8 %4, i8 %1<br>
+  %7 = xor i8 %6, -1<br>
+  %sub34 = sub i8 %6, %0<br>
+  %sub38 = sub i8 %6, %1<br>
+  %sub42 = sub i8 %6, %2<br>
+  %incdec.ptr44 = getelementptr inbounds i8, i8* %B.addr.0, i32 1<br>
+  store i8 %7, i8* %B.addr.0, align 1<br>
+  %incdec.ptr45 = getelementptr inbounds i8, i8* %B.addr.0, i32 2<br>
+  store i8 %sub34, i8* %incdec.ptr44, align 1<br>
+  %incdec.ptr46 = getelementptr inbounds i8, i8* %B.addr.0, i32 3<br>
+  store i8 %sub38, i8* %incdec.ptr45, align 1<br>
+  %incdec.ptr47 = getelementptr inbounds i8, i8* %B.addr.0, i32 4<br>
+  store i8 %sub42, i8* %incdec.ptr46, align 1<br>
+  %inc = add nuw nsw i32 %i.0, 1<br>
+  br label %for.cond<br>
+<br>
+for.cond.cleanup:                                 ; preds = %for.cond<br>
+  ret void<br>
+}<br>
+<br>
+<br>
+attributes #0 = { minsize optsize }<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div>