]> granicus.if.org Git - llvm/commitdiff
[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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@373186 91177308-0d34-0410-b5e6-96231b3b80d8

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

index 9c8da29febf988aed431151b56c02c483c699a0c..1c2c8aef55bb806aa30ba956bd1aea69958adf38 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 4873b8836502afff18f81926d5a6742b81f1910c..c446ddbdd07a7d5b9037624aa26537280adfddd6 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 e7adc5ae2491b2517c5109cd670081e13f63bb59..9b07a80e9a1c1452ba6ba1ffdf0a51448e195339 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 44f3829c6b4427f3443a9b3c55fc1d464c5a5ecf..596893724d20356c6001f6d3d7b00c6e80cf3583 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
 }
+