diff options
author | Matt Arsenault <Matthew.Arsenault@amd.com> | 2013-10-29 20:59:29 +0000 |
---|---|---|
committer | Matt Arsenault <Matthew.Arsenault@amd.com> | 2013-10-29 20:59:29 +0000 |
commit | 2b0002b579dba5604a2673bbee2cd9969e183a71 (patch) | |
tree | 6a0a29807f6406e8efcda11a24e0eeada14d292d /include | |
parent | 5203b7773e29b36e38aac0ce9358fa7843065681 (diff) | |
download | external_llvm-2b0002b579dba5604a2673bbee2cd9969e183a71.zip external_llvm-2b0002b579dba5604a2673bbee2cd9969e183a71.tar.gz external_llvm-2b0002b579dba5604a2673bbee2cd9969e183a71.tar.bz2 |
Workaround MSVC 32-bit miscompile of getCondCodeAction.
Use 32-bit types for the array instead of 64. This should
generally be better anyway.
In optimized + assert builds, I saw a failure when a
cond code / type combination that is never set was loading
a non-zero value and hitting the != Promote assert.
It turns out when loading the 64-bit value to do the shift,
the assembly loads the 2 32-bit halves from non-consecutive
addresses. The address the second half of the loaded uint64_t
doesn't include the offset of the array in the struct. Instead
of being offset + 4, it's just + 4.
I'm not entirely sure why this wasn't observed before.
setCondCodeAction isn't heavily used by the in-tree targets,
and not with the higher valued vector SimpleValueTypes. Only
PPC is using one of the > 32 valued types, and that is probably
never used by anyone on a 32-bit MSVC compiled host.
I ran into this when upgrading LLVM versions, so I guess the
value loaded from the nonsense address happened to work out
before.
No test since I'm not really sure if / how it can be reproduced
with the current in tree targets, and it's not supposed to change
anything.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@193650 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include')
-rw-r--r-- | include/llvm/Target/TargetLowering.h | 28 |
1 files changed, 13 insertions, 15 deletions
diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index 3cde173..5b9e377 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -520,13 +520,12 @@ public: LegalizeAction getCondCodeAction(ISD::CondCode CC, MVT VT) const { assert((unsigned)CC < array_lengthof(CondCodeActions) && - (unsigned)VT.SimpleTy < sizeof(CondCodeActions[0])*4 && + ((unsigned)VT.SimpleTy >> 4) < array_lengthof(CondCodeActions[0]) && "Table isn't big enough!"); - /// The lower 5 bits of the SimpleTy index into Nth 2bit set from the 64bit - /// value and the upper 27 bits index into the second dimension of the - /// array to select what 64bit value to use. - LegalizeAction Action = (LegalizeAction) - ((CondCodeActions[CC][VT.SimpleTy >> 5] >> (2*(VT.SimpleTy & 0x1F))) & 3); + // See setCondCodeAction for how this is encoded. + uint32_t Shift = 2 * (VT.SimpleTy & 0xF); + uint32_t Value = CondCodeActions[CC][VT.SimpleTy >> 4]; + LegalizeAction Action = (LegalizeAction) ((Value >> Shift) & 0x3); assert(Action != Promote && "Can't promote condition code!"); return Action; } @@ -1020,13 +1019,12 @@ protected: assert(VT < MVT::LAST_VALUETYPE && (unsigned)CC < array_lengthof(CondCodeActions) && "Table isn't big enough!"); - /// The lower 5 bits of the SimpleTy index into Nth 2bit set from the 64bit - /// value and the upper 27 bits index into the second dimension of the - /// array to select what 64bit value to use. - CondCodeActions[(unsigned)CC][VT.SimpleTy >> 5] - &= ~(uint64_t(3UL) << (VT.SimpleTy & 0x1F)*2); - CondCodeActions[(unsigned)CC][VT.SimpleTy >> 5] - |= (uint64_t)Action << (VT.SimpleTy & 0x1F)*2; + /// The lower 5 bits of the SimpleTy index into Nth 2bit set from the 32-bit + /// value and the upper 27 bits index into the second dimension of the array + /// to select what 32-bit value to use. + uint32_t Shift = 2 * (VT.SimpleTy & 0xF); + CondCodeActions[CC][VT.SimpleTy >> 4] &= ~((uint32_t)0x3 << Shift); + CondCodeActions[CC][VT.SimpleTy >> 4] |= (uint32_t)Action << Shift; } /// If Opc/OrigVT is specified as being promoted, the promotion code defaults @@ -1448,8 +1446,8 @@ private: /// /// Because each CC action takes up 2 bits, we need to have the array size be /// large enough to fit all of the value types. This can be done by dividing - /// the MVT::LAST_VALUETYPE by 32 and adding one. - uint64_t CondCodeActions[ISD::SETCC_INVALID][(MVT::LAST_VALUETYPE / 32) + 1]; + /// the MVT::LAST_VALUETYPE by 16 and adding one. + uint32_t CondCodeActions[ISD::SETCC_INVALID][(MVT::LAST_VALUETYPE + 15) / 16]; ValueTypeActionImpl ValueTypeActions; |