[llvm] r220553 - [AArch64] Fix fast-isel of cbz of i1, i8, i16

Oliver Stannard oliver.stannard at arm.com
Fri Oct 24 02:54:41 PDT 2014


Author: olista01
Date: Fri Oct 24 04:54:41 2014
New Revision: 220553

URL: http://llvm.org/viewvc/llvm-project?rev=220553&view=rev
Log:
[AArch64] Fix fast-isel of cbz of i1, i8, i16

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.


Modified:
    llvm/trunk/lib/Target/AArch64/AArch64FastISel.cpp
    llvm/trunk/test/CodeGen/AArch64/fast-isel-cbz.ll

Modified: llvm/trunk/lib/Target/AArch64/AArch64FastISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64FastISel.cpp?rev=220553&r1=220552&r2=220553&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64FastISel.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64FastISel.cpp Fri Oct 24 04:54:41 2014
@@ -2181,6 +2181,12 @@ bool AArch64FastISel::emitCompareAndBran
     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 =

Modified: llvm/trunk/test/CodeGen/AArch64/fast-isel-cbz.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/fast-isel-cbz.ll?rev=220553&r1=220552&r2=220553&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/fast-isel-cbz.ll (original)
+++ llvm/trunk/test/CodeGen/AArch64/fast-isel-cbz.ll Fri Oct 24 04:54:41 2014
@@ -1,8 +1,9 @@
 ; 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:       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:
@@ -11,9 +12,10 @@ bb1:
   ret i32 0
 }
 
-define i32 @icmp_eq_i8(i8 signext %a) {
+define i32 @icmp_eq_i8(i8 %a) {
 ; 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:
@@ -22,9 +24,10 @@ bb1:
   ret i32 0
 }
 
-define i32 @icmp_eq_i16(i16 signext %a) {
+define i32 @icmp_eq_i16(i16 %a) {
 ; 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:





More information about the llvm-commits mailing list