From a0288535408cb58797a27465fed838753fcc6238 Mon Sep 17 00:00:00 2001 From: Saleem Abdulrasool Date: Thu, 21 Apr 2016 23:53:19 +0000 Subject: [PATCH] ARM: restrict register class for WIN__DBZCHK WIN__DBZCHK will insert a CBZ instruction into the stream. This instruction reserves 3 bits for the condition register (rn). As such, we must ensure that we restrict the register to a low register. Use the tGPR class instead of GPR to ensure that this is properly constrained. In debug builds, we would attempt to use lr as a condition register which would silently get truncated with no hint that the register selection was incorrect. llvm-svn: 267080 --- llvm/lib/Target/ARM/ARMInstrInfo.td | 4 +-- llvm/test/CodeGen/ARM/Windows/dbzchk.ll | 47 +++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Target/ARM/ARMInstrInfo.td b/llvm/lib/Target/ARM/ARMInstrInfo.td index 3f32dd7..25472b5 100644 --- a/llvm/lib/Target/ARM/ARMInstrInfo.td +++ b/llvm/lib/Target/ARM/ARMInstrInfo.td @@ -5284,8 +5284,8 @@ let usesCustomInserter = 1, Uses = [R4], Defs = [R4, SP] in def win__dbzchk : SDNode<"ARMISD::WIN__DBZCHK", SDT_WIN__DBZCHK, [SDNPHasChain, SDNPSideEffect, SDNPOutGlue]>; let usesCustomInserter = 1, Defs = [CPSR] in - def WIN__DBZCHK : PseudoInst<(outs), (ins GPR:$divisor), NoItinerary, - [(win__dbzchk GPR:$divisor)]>; + def WIN__DBZCHK : PseudoInst<(outs), (ins tGPR:$divisor), NoItinerary, + [(win__dbzchk tGPR:$divisor)]>; //===----------------------------------------------------------------------===// // TLS Instructions diff --git a/llvm/test/CodeGen/ARM/Windows/dbzchk.ll b/llvm/test/CodeGen/ARM/Windows/dbzchk.ll index 9019545..bb25527 100644 --- a/llvm/test/CodeGen/ARM/Windows/dbzchk.ll +++ b/llvm/test/CodeGen/ARM/Windows/dbzchk.ll @@ -142,3 +142,50 @@ attributes #0 = { optsize } ; CHECK-CFG: bl __rt_udiv ; CHECK-CFG: pop.w {{{.*}}, r11, pc} +; RUN: llc -O0 -mtriple thumbv7--windows-itanium -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-WIN__DBZCHK + +; long k(void); +; int l(void); +; int j(int i) { +; if (l() == -1) +; return 0; +; return k() % i; +; } + +declare arm_aapcs_vfpcc i32 @k() +declare arm_aapcs_vfpcc i32 @l() + +define arm_aapcs_vfpcc i32 @j(i32 %i) { +entry: + %retval = alloca i32, align 4 + %i.addr = alloca i32, align 4 + store i32 %i, i32* %i.addr, align 4 + %call = call arm_aapcs_vfpcc i32 @l() + %cmp = icmp eq i32 %call, -1 + br i1 %cmp, label %if.then, label %if.end + +if.then: + store i32 0, i32* %retval, align 4 + br label %return + +if.end: + %call1 = call arm_aapcs_vfpcc i32 @k() + %0 = load i32, i32* %i.addr, align 4 + %rem = srem i32 %call1, %0 + store i32 %rem, i32* %retval, align 4 + br label %return + +return: + %1 = load i32, i32* %retval, align 4 + ret i32 %1 +} + +; CHECK-WIN__DBZCHK-LABEL: j: +; CHECK-WIN__DBZCHK: cbz r{{[0-7]}}, .LBB +; CHECK-WIN__DBZCHK-NOT: cbz r8, .LBB +; CHECK-WIN__DBZCHK-NOT: cbz r9, .LBB +; CHECK-WIN__DBZCHK-NOT: cbz r10, .LBB +; CHECK-WIN__DBZCHK-NOT: cbz r11, .LBB +; CHECK-WIN__DBZCHK-NOT: cbz ip, .LBB +; CHECK-WIN__DBZCHK-NOT: cbz lr, .LBB + -- 2.7.4