This fixes a miscompilation in the AArch64 fast-isel which was
triggered when a branch is based on an icmp with condition eq or ne,
and type i1, i8 or i16. The cbz instruction compares the whole 32-bit
register, so values with the bottom 1, 8 or 16 bits clear would cause
the wrong branch to be taken.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@220553
91177308-0d34-0410-b5e6-
96231b3b80d8
SrcReg = fastEmitInst_extractsubreg(MVT::i32, SrcReg, SrcIsKill,
AArch64::sub_32);
SrcReg = fastEmitInst_extractsubreg(MVT::i32, SrcReg, SrcIsKill,
AArch64::sub_32);
+ if ((BW < 32) && !IsBitTest) {
+ EVT CmpEVT = TLI.getValueType(Ty, true);
+ SrcReg =
+ emitIntExt(CmpEVT.getSimpleVT(), SrcReg, MVT::i32, /*isZExt*/ true);
+ }
+
// Emit the combined compare and branch instruction.
SrcReg = constrainOperandRegClass(II, SrcReg, II.getNumDefs());
MachineInstrBuilder MIB =
// Emit the combined compare and branch instruction.
SrcReg = constrainOperandRegClass(II, SrcReg, II.getNumDefs());
MachineInstrBuilder MIB =
; RUN: llc -fast-isel -fast-isel-abort -aarch64-atomic-cfg-tidy=0 -verify-machineinstrs -mtriple=aarch64-apple-darwin < %s | FileCheck %s
; RUN: llc -fast-isel -fast-isel-abort -aarch64-atomic-cfg-tidy=0 -verify-machineinstrs -mtriple=aarch64-apple-darwin < %s | FileCheck %s
-define i32 @icmp_eq_i1(i1 signext %a) {
+define i32 @icmp_eq_i1(i1 %a) {
; CHECK-LABEL: icmp_eq_i1
; CHECK-LABEL: icmp_eq_i1
-; CHECK: cbz w0, {{LBB.+_2}}
+; CHECK: and [[REG:w[0-9]+]], w0, #0x1
+; CHECK: cbz [[REG]], {{LBB.+_2}}
%1 = icmp eq i1 %a, 0
br i1 %1, label %bb1, label %bb2
bb2:
%1 = icmp eq i1 %a, 0
br i1 %1, label %bb1, label %bb2
bb2:
-define i32 @icmp_eq_i8(i8 signext %a) {
+define i32 @icmp_eq_i8(i8 %a) {
; CHECK-LABEL: icmp_eq_i8
; CHECK-LABEL: icmp_eq_i8
-; CHECK: cbz w0, {{LBB.+_2}}
+; CHECK: uxtb [[REG:w[0-9]+]], w0
+; CHECK: cbz [[REG]], {{LBB.+_2}}
%1 = icmp eq i8 %a, 0
br i1 %1, label %bb1, label %bb2
bb2:
%1 = icmp eq i8 %a, 0
br i1 %1, label %bb1, label %bb2
bb2:
-define i32 @icmp_eq_i16(i16 signext %a) {
+define i32 @icmp_eq_i16(i16 %a) {
; CHECK-LABEL: icmp_eq_i16
; CHECK-LABEL: icmp_eq_i16
-; CHECK: cbz w0, {{LBB.+_2}}
+; CHECK: uxth [[REG:w[0-9]+]], w0
+; CHECK: cbz [[REG]], {{LBB.+_2}}
%1 = icmp eq i16 %a, 0
br i1 %1, label %bb1, label %bb2
bb2:
%1 = icmp eq i16 %a, 0
br i1 %1, label %bb1, label %bb2
bb2: