mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-12 01:25:49 +00:00
[AArch64] Fix a type conversion bug for anlyzing compare.
The bug can cause spec2006/483.xalancbmk failure. Patched by David Xu. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@215206 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -641,7 +641,8 @@ bool AArch64InstrInfo::analyzeCompare(const MachineInstr *MI, unsigned &SrcReg,
|
|||||||
SrcReg = MI->getOperand(1).getReg();
|
SrcReg = MI->getOperand(1).getReg();
|
||||||
SrcReg2 = 0;
|
SrcReg2 = 0;
|
||||||
CmpMask = ~0;
|
CmpMask = ~0;
|
||||||
CmpValue = MI->getOperand(2).getImm();
|
// FIXME: In order to convert CmpValue to 0 or 1
|
||||||
|
CmpValue = (MI->getOperand(2).getImm() != 0);
|
||||||
return true;
|
return true;
|
||||||
case AArch64::ANDSWri:
|
case AArch64::ANDSWri:
|
||||||
case AArch64::ANDSXri:
|
case AArch64::ANDSXri:
|
||||||
@@ -650,9 +651,14 @@ bool AArch64InstrInfo::analyzeCompare(const MachineInstr *MI, unsigned &SrcReg,
|
|||||||
SrcReg = MI->getOperand(1).getReg();
|
SrcReg = MI->getOperand(1).getReg();
|
||||||
SrcReg2 = 0;
|
SrcReg2 = 0;
|
||||||
CmpMask = ~0;
|
CmpMask = ~0;
|
||||||
CmpValue = AArch64_AM::decodeLogicalImmediate(
|
// FIXME:The return val type of decodeLogicalImmediate is uint64_t,
|
||||||
MI->getOperand(2).getImm(),
|
// while the type of CmpValue is int. When converting uint64_t to int,
|
||||||
MI->getOpcode() == AArch64::ANDSWri ? 32 : 64);
|
// the high 32 bits of uint64_t will be lost.
|
||||||
|
// In fact it causes a bug in spec2006-483.xalancbmk
|
||||||
|
// CmpValue is only used to compare with zero in OptimizeCompareInstr
|
||||||
|
CmpValue = (AArch64_AM::decodeLogicalImmediate(
|
||||||
|
MI->getOperand(2).getImm(),
|
||||||
|
MI->getOpcode() == AArch64::ANDSWri ? 32 : 64) != 0);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -749,6 +755,9 @@ bool AArch64InstrInfo::optimizeCompareInstr(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Continue only if we have a "ri" where immediate is zero.
|
// Continue only if we have a "ri" where immediate is zero.
|
||||||
|
// FIXME:CmpValue has already been converted to 0 or 1 in analyzeCompare
|
||||||
|
// function.
|
||||||
|
assert((CmpValue == 0 || CmpValue == 1) && "CmpValue must be 0 or 1!");
|
||||||
if (CmpValue != 0 || SrcReg2 != 0)
|
if (CmpValue != 0 || SrcReg2 != 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
32
test/CodeGen/AArch64/analyzecmp.ll
Normal file
32
test/CodeGen/AArch64/analyzecmp.ll
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
; RUN: llc -O3 -mcpu=cortex-a57 < %s | FileCheck %s
|
||||||
|
|
||||||
|
; CHECK-LABLE: @test
|
||||||
|
; CHECK: tst [[CMP:x[0-9]+]], #0x8000000000000000
|
||||||
|
; CHECK: csel [[R0:x[0-9]+]], [[S0:x[0-9]+]], [[S1:x[0-9]+]], eq
|
||||||
|
; CHECK: csel [[R1:x[0-9]+]], [[S2:x[0-9]+]], [[S3:x[0-9]+]], eq
|
||||||
|
target datalayout = "e-m:e-i64:64-i128:128-n32:64-S128"
|
||||||
|
target triple = "arm64--linux-gnueabi"
|
||||||
|
|
||||||
|
define void @test(i64 %a, i64* %ptr1, i64* %ptr2) #0 align 2 {
|
||||||
|
entry:
|
||||||
|
%conv = and i64 %a, 4294967295
|
||||||
|
%add = add nsw i64 %conv, -1
|
||||||
|
%div = sdiv i64 %add, 64
|
||||||
|
%rem = srem i64 %add, 64
|
||||||
|
%cmp = icmp slt i64 %rem, 0
|
||||||
|
br i1 %cmp, label %if.then, label %exit
|
||||||
|
|
||||||
|
if.then:
|
||||||
|
%add2 = add nsw i64 %rem, 64
|
||||||
|
%add3 = add i64 %div, -1
|
||||||
|
br label %exit
|
||||||
|
|
||||||
|
exit:
|
||||||
|
%__n = phi i64 [ %add3, %if.then ], [ %div, %entry ]
|
||||||
|
%__n.0 = phi i64 [ %add2, %if.then ], [ %rem, %entry ]
|
||||||
|
store i64 %__n, i64* %ptr1
|
||||||
|
store i64 %__n.0, i64* %ptr2
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Reference in New Issue
Block a user