[llvm] r297208 - [GlobalISel] Avoid invalidating ValToVReg when translating no-op bitcast.

Ahmed Bougacha via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 7 12:53:06 PST 2017


Author: ab
Date: Tue Mar  7 14:53:06 2017
New Revision: 297208

URL: http://llvm.org/viewvc/llvm-project?rev=297208&view=rev
Log:
[GlobalISel] Avoid invalidating ValToVReg when translating no-op bitcast.

When we translate a no-op (same type) bitcast, we try to be clever and
only emit a COPY if we already assigned a vreg to the defined value.
However, when we didn't, we tried to assign to a reference into the
ValToVReg DenseMap, even though the RHS of the assignment
(getOrCreateVReg) could potentially grow that DenseMap, invalidating the
reference.

Avoid that by getting the source vreg first.
I audited the rest of the translator; this is the only tricky case.

The test is quite unwieldy, as the problem is caused by the DenseMap
growing, which happens after the 47th mapped value.

Added:
    llvm/trunk/test/CodeGen/AArch64/GlobalISel/irtranslator-bitcast.ll
Modified:
    llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp

Modified: llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp?rev=297208&r1=297207&r2=297208&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp (original)
+++ llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp Tue Mar  7 14:53:06 2017
@@ -396,12 +396,17 @@ bool IRTranslator::translateSelect(const
 
 bool IRTranslator::translateBitCast(const User &U,
                                     MachineIRBuilder &MIRBuilder) {
+  // If we're bitcasting to the source type, we can reuse the source vreg.
   if (LLT{*U.getOperand(0)->getType(), *DL} == LLT{*U.getType(), *DL}) {
+    // Get the source vreg now, to avoid invalidating ValToVReg.
+    unsigned SrcReg = getOrCreateVReg(*U.getOperand(0));
     unsigned &Reg = ValToVReg[&U];
+    // If we already assigned a vreg for this bitcast, we can't change that.
+    // Emit a copy to satisfy the users we already emitted.
     if (Reg)
-      MIRBuilder.buildCopy(Reg, getOrCreateVReg(*U.getOperand(0)));
+      MIRBuilder.buildCopy(Reg, SrcReg);
     else
-      Reg = getOrCreateVReg(*U.getOperand(0));
+      Reg = SrcReg;
     return true;
   }
   return translateCast(TargetOpcode::G_BITCAST, U, MIRBuilder);

Added: llvm/trunk/test/CodeGen/AArch64/GlobalISel/irtranslator-bitcast.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/GlobalISel/irtranslator-bitcast.ll?rev=297208&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/GlobalISel/irtranslator-bitcast.ll (added)
+++ llvm/trunk/test/CodeGen/AArch64/GlobalISel/irtranslator-bitcast.ll Tue Mar  7 14:53:06 2017
@@ -0,0 +1,30 @@
+; RUN: llc -O0 -mtriple=aarch64-apple-ios -global-isel -stop-after=irtranslator %s -o - | FileCheck %s
+
+; Check that we don't invalidate the vreg map.
+; This test is brittle: the invalidation only triggers when we grow the map.
+
+; CHECK-LABEL: name: test_bitcast_invalid_vreg
+define i32 @test_bitcast_invalid_vreg() {
+  %tmp0 = add i32 1, 2
+  %tmp1 = add i32 3, 4
+  %tmp2 = add i32 5, 6
+  %tmp3 = add i32 7, 8
+  %tmp4 = add i32 9, 10
+  %tmp5 = add i32 11, 12
+  %tmp6 = add i32 13, 14
+  %tmp7 = add i32 15, 16
+  %tmp8 = add i32 17, 18
+  %tmp9 = add i32 19, 20
+  %tmp10 = add i32 21, 22
+  %tmp11 = add i32 23, 24
+  %tmp12 = add i32 25, 26
+  %tmp13 = add i32 27, 28
+  %tmp14 = add i32 29, 30
+  %tmp15 = add i32 30, 30
+
+; At this point we mapped 46 values. The 'i32 100' constant will grow the map.
+; CHECK:  %46(s32) = G_CONSTANT i32 100
+; CHECK:  %w0 = COPY %46(s32)
+  %res = bitcast i32 100 to i32
+  ret i32 %res
+}




More information about the llvm-commits mailing list