[ARM][CGP] Allow signext arguments
authorSam Parker <sam.parker@arm.com>
Mon, 30 Sep 2019 07:52:10 +0000 (07:52 +0000)
committerSam Parker <sam.parker@arm.com>
Mon, 30 Sep 2019 07:52:10 +0000 (07:52 +0000)
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

llvm/lib/Target/ARM/ARMCodeGenPrepare.cpp
llvm/test/CodeGen/ARM/CGP/arm-cgp-overflow.ll
llvm/test/CodeGen/ARM/CGP/arm-cgp-phis-ret.ll
llvm/test/CodeGen/ARM/CGP/arm-cgp-signed.ll

index 9c8da29..1c2c8ae 100644 (file)
@@ -179,9 +179,6 @@ public:
 }
 
 static bool GenerateSignBits(Value *V) {
-  if (auto *Arg = dyn_cast<Argument>(V))
-    return Arg->hasSExtAttr();
-
   if (!isa<Instruction>(V))
     return false;
 
@@ -843,8 +840,8 @@ bool ARMCodeGenPrepare::isSupportedValue(Value *V) {
     }
   } else if (isa<Constant>(V) && !isa<ConstantExpr>(V)) {
     return isSupportedType(V);
-  } else if (auto *Arg = dyn_cast<Argument>(V))
-    return isSupportedType(V) && !Arg->hasSExtAttr();
+  } else if (isa<Argument>(V))
+    return isSupportedType(V);
 
   return isa<BasicBlock>(V);
 }
index 4873b88..c446ddb 100644 (file)
@@ -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
index e7adc5a..9b07a80 100644 (file)
@@ -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
+}
index 44f3829..5968937 100644 (file)
@@ -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
 }
+