From 01dc2b357d748665771a418aeb962bb4dd6dbd76 Mon Sep 17 00:00:00 2001 From: Sam Parker Date: Mon, 30 Sep 2019 07:52:10 +0000 Subject: [PATCH] [ARM][CGP] Allow signext arguments As we perform a zext on any arguments used in the promoted tree, it doesn't matter if they're marked as signext. The only permitted user(s) in the tree which would interpret the sign bits are signed icmps. For these instructions, their promoted operands are truncated before the icmp uses them. Differential Revision: https://reviews.llvm.org/D68019 llvm-svn: 373186 --- lib/Target/ARM/ARMCodeGenPrepare.cpp | 7 ++---- test/CodeGen/ARM/CGP/arm-cgp-overflow.ll | 7 +++--- test/CodeGen/ARM/CGP/arm-cgp-phis-ret.ll | 32 ++++++++++++++++++++++++ test/CodeGen/ARM/CGP/arm-cgp-signed.ll | 31 ++++++++++++++++++----- 4 files changed, 62 insertions(+), 15 deletions(-) diff --git a/lib/Target/ARM/ARMCodeGenPrepare.cpp b/lib/Target/ARM/ARMCodeGenPrepare.cpp index 9c8da29febf..1c2c8aef55b 100644 --- a/lib/Target/ARM/ARMCodeGenPrepare.cpp +++ b/lib/Target/ARM/ARMCodeGenPrepare.cpp @@ -179,9 +179,6 @@ public: } static bool GenerateSignBits(Value *V) { - if (auto *Arg = dyn_cast(V)) - return Arg->hasSExtAttr(); - if (!isa(V)) return false; @@ -843,8 +840,8 @@ bool ARMCodeGenPrepare::isSupportedValue(Value *V) { } } else if (isa(V) && !isa(V)) { return isSupportedType(V); - } else if (auto *Arg = dyn_cast(V)) - return isSupportedType(V) && !Arg->hasSExtAttr(); + } else if (isa(V)) + return isSupportedType(V); return isa(V); } diff --git a/test/CodeGen/ARM/CGP/arm-cgp-overflow.ll b/test/CodeGen/ARM/CGP/arm-cgp-overflow.ll index 4873b883650..c446ddbdd07 100644 --- a/test/CodeGen/ARM/CGP/arm-cgp-overflow.ll +++ b/test/CodeGen/ARM/CGP/arm-cgp-overflow.ll @@ -264,10 +264,9 @@ define i8 @underflow_if_sub(i32 %arg, i8 zeroext %arg1) { } ; CHECK-LABEL: underflow_if_sub_signext -; CHECK: uxtb [[UXT1:r[0-9]+]], r1 -; CHECK: sub{{.*}} [[SUB:r[0-9]+]], #11 -; CHECK: uxtb [[UXT_SUB:r[0-9]+]], [[SUB]] -; CHECK: cmp{{.*}}[[UXT_SUB]] +; CHECK: cmp r0, #0 +; CHECK-NEXT: uxtb r1, r1 +; CHECK-NOT: xtb define i8 @underflow_if_sub_signext(i32 %arg, i8 signext %arg1) { %cmp = icmp sgt i32 %arg, 0 %conv = zext i1 %cmp to i32 diff --git a/test/CodeGen/ARM/CGP/arm-cgp-phis-ret.ll b/test/CodeGen/ARM/CGP/arm-cgp-phis-ret.ll index e7adc5ae249..9b07a80e9a1 100644 --- a/test/CodeGen/ARM/CGP/arm-cgp-phis-ret.ll +++ b/test/CodeGen/ARM/CGP/arm-cgp-phis-ret.ll @@ -184,3 +184,35 @@ define i16 @promote_arg_return(i16 zeroext %arg1, i16 zeroext %arg2, i8* %res) { store i8 %conv, i8* %res ret i16 %arg1 } + +; CHECK-COMMON-LABEL: signext_bitcast_phi_select +; CHECK: uxth [[UXT:r[0-9]+]], r0 +; CHECK: sxth [[SXT:r[0-9]+]], [[UXT]] +; CHECK: cmp [[SXT]], +; CHECK-NOT: xth +define i16 @signext_bitcast_phi_select(i16 signext %start, i16* %in) { +entry: + %const = bitcast i16 -1 to i16 + br label %for.body + +for.body: + %idx = phi i16 [ %select, %if.else ], [ %start, %entry ] + %cmp.i = icmp sgt i16 %idx, %const + br i1 %cmp.i, label %exit, label %if.then + +if.then: + %idx.next = getelementptr i16, i16* %in, i16 %idx + %ld = load i16, i16* %idx.next, align 2 + %cmp1.i = icmp eq i16 %ld, %idx + br i1 %cmp1.i, label %exit, label %if.else + +if.else: + %lobit = lshr i16 %idx, 15 + %lobit.not = xor i16 %lobit, 1 + %select = add nuw i16 %lobit.not, %idx + br label %for.body + +exit: + %res = phi i16 [ %ld, %if.then ], [ 0, %for.body ] + ret i16 %res +} diff --git a/test/CodeGen/ARM/CGP/arm-cgp-signed.ll b/test/CodeGen/ARM/CGP/arm-cgp-signed.ll index 44f3829c6b4..596893724d2 100644 --- a/test/CodeGen/ARM/CGP/arm-cgp-signed.ll +++ b/test/CodeGen/ARM/CGP/arm-cgp-signed.ll @@ -1,5 +1,5 @@ -; RUN: llc -mtriple=thumbv7m -arm-disable-cgp=false %s -o - | FileCheck %s -; RUN: llc -mtriple=thumbv8m.main -arm-disable-cgp=false %s -o - | FileCheck %s +; RUN: llc -mtriple=thumbv7em -arm-disable-cgp=false %s -o - | FileCheck %s +; RUN: llc -mtriple=thumbv8m.main -mattr=+dsp -arm-disable-cgp=false %s -o - | FileCheck %s ; RUN: llc -mtriple=thumbv7 %s -arm-disable-cgp=false -o - | FileCheck %s ; RUN: llc -mtriple=armv8 %s -arm-disable-cgp=false -o - | FileCheck %s @@ -45,8 +45,8 @@ define i16 @test_srem(i16 zeroext %arg) { ; CHECK-LABEL: test_signext_b ; CHECK: ldrb [[LDR:r[0-9]+]], [r0] -; CHECK: sxtb [[SXT:r[0-9]+]], [[LDR]] -; CHECK: cm{{.*}} [[SXT]] +; CHECK: uxtab [[UXT:r[0-9]+]], [[LDR]], r1 +; CHECK: cm{{.*}} [[UXT]], #128 define i32 @test_signext_b(i8* %ptr, i8 signext %arg) { entry: %0 = load i8, i8* %ptr, align 1 @@ -56,10 +56,28 @@ entry: ret i32 %res } +; CHECK-LABEL: test_signext_b_ult_slt +; CHECK: ldrb [[LDR:r[0-9]+]], [r0] +; CHECK: uxtab [[ADD:r[0-9]+]], [[LDR]], r1 +; CHECK: uxtb [[UXT:r[0-9]+]], r1 +; CHECK: cmp [[ADD]], [[UXT]] +; CHECK: uxtb [[TRUNC:r[0-9]+]], [[ADD]] +; CHECK: cmp [[TRUNC]], #127 +define i32 @test_signext_b_ult_slt(i8* %ptr, i8 signext %arg) { +entry: + %0 = load i8, i8* %ptr, align 1 + %1 = add nuw nsw i8 %0, %arg + %cmp = icmp sle i8 %1, 126 + %cmp.1 = icmp ule i8 %1, %arg + %or = and i1 %cmp, %cmp.1 + %res = select i1 %or, i32 42, i32 57 + ret i32 %res +} + ; CHECK-LABEL: test_signext_h ; CHECK: ldrh [[LDR:r[0-9]+]], [r0] -; CHECK: sxth [[SXT:r[0-9]+]], [[LDR]] -; CHECK: cm{{.*}} [[SXT]] +; CHECK: uxtah [[ADD:r[0-9]+]], [[LDR]], r1 +; CHECK: cm{{.*}} [[ADD]], define i32 @test_signext_h(i16* %ptr, i16 signext %arg) { entry: %0 = load i16, i16* %ptr, align 1 @@ -68,3 +86,4 @@ entry: %res = select i1 %cmp, i32 42, i32 20894 ret i32 %res } +