[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