mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 03:02:36 +01:00
[ARM] Handle all-ones mask explicitly in targetShrinkDemandedConstant.
This avoids a potential infinite loop setting and unsetting bits in the mask. Reduced from a failure on the polly-aosp bot. Differential Revision: https://reviews.llvm.org/D51066 llvm-svn: 340446
This commit is contained in:
parent
facf6eb783
commit
c4518513f4
@ -13647,14 +13647,21 @@ ARMTargetLowering::targetShrinkDemandedConstant(SDValue Op,
|
|||||||
|
|
||||||
unsigned Mask = C->getZExtValue();
|
unsigned Mask = C->getZExtValue();
|
||||||
|
|
||||||
// If mask is zero, nothing to do.
|
|
||||||
if (!Mask)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
unsigned Demanded = DemandedAPInt.getZExtValue();
|
unsigned Demanded = DemandedAPInt.getZExtValue();
|
||||||
unsigned ShrunkMask = Mask & Demanded;
|
unsigned ShrunkMask = Mask & Demanded;
|
||||||
unsigned ExpandedMask = Mask | ~Demanded;
|
unsigned ExpandedMask = Mask | ~Demanded;
|
||||||
|
|
||||||
|
// If the mask is all zeros, let the target-independent code replace the
|
||||||
|
// result with zero.
|
||||||
|
if (ShrunkMask == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// If the mask is all ones, erase the AND. (Currently, the target-independent
|
||||||
|
// code won't do this, so we have to do it explicitly to avoid an infinite
|
||||||
|
// loop in obscure cases.)
|
||||||
|
if (ExpandedMask == ~0U)
|
||||||
|
return TLO.CombineTo(Op, Op.getOperand(0));
|
||||||
|
|
||||||
auto IsLegalMask = [ShrunkMask, ExpandedMask](unsigned Mask) -> bool {
|
auto IsLegalMask = [ShrunkMask, ExpandedMask](unsigned Mask) -> bool {
|
||||||
return (ShrunkMask & Mask) == ShrunkMask && (~ExpandedMask & Mask) == 0;
|
return (ShrunkMask & Mask) == ShrunkMask && (~ExpandedMask & Mask) == 0;
|
||||||
};
|
};
|
||||||
|
35
test/CodeGen/ARM/demanded-bits-and.ll
Normal file
35
test/CodeGen/ARM/demanded-bits-and.ll
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||||
|
; RUN: llc -mtriple=arm-eabi < %s | FileCheck %s
|
||||||
|
|
||||||
|
; Make sure this doesn't hang, and there are no unnecessary
|
||||||
|
; "and" instructions.
|
||||||
|
|
||||||
|
define dso_local void @f(i16* %p) {
|
||||||
|
; CHECK-LABEL: f:
|
||||||
|
; CHECK: @ %bb.0: @ %entry
|
||||||
|
; CHECK-NEXT: .LBB0_1: @ %bb
|
||||||
|
; CHECK-NEXT: @ =>This Inner Loop Header: Depth=1
|
||||||
|
; CHECK-NEXT: ldrh r1, [r0]
|
||||||
|
; CHECK-NEXT: and r2, r1, #255
|
||||||
|
; CHECK-NEXT: add r3, r2, r1, lsr #8
|
||||||
|
; CHECK-NEXT: add r2, r3, r2
|
||||||
|
; CHECK-NEXT: add r1, r2, r1, lsr #8
|
||||||
|
; CHECK-NEXT: add r1, r1, #2
|
||||||
|
; CHECK-NEXT: lsr r1, r1, #2
|
||||||
|
; CHECK-NEXT: strh r1, [r0]
|
||||||
|
; CHECK-NEXT: b .LBB0_1
|
||||||
|
entry:
|
||||||
|
br label %bb
|
||||||
|
|
||||||
|
bb:
|
||||||
|
%_p_scalar_ = load i16, i16* %p, align 2
|
||||||
|
%p_and = and i16 %_p_scalar_, 255
|
||||||
|
%p_ = lshr i16 %_p_scalar_, 8
|
||||||
|
%p_add = add nuw nsw i16 %p_, 2
|
||||||
|
%p_add14 = add nuw nsw i16 %p_add, %p_and
|
||||||
|
%p_add18 = add nuw nsw i16 %p_add14, %p_and
|
||||||
|
%p_add19 = add nuw nsw i16 %p_add18, %p_
|
||||||
|
%p_200 = lshr i16 %p_add19, 2
|
||||||
|
store i16 %p_200, i16* %p, align 2
|
||||||
|
br label %bb
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user