[llvm] r351935 - [ARM][CGP] Check trunc type before replacing

Sam Parker via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 23 01:18:44 PST 2019


Author: sam_parker
Date: Wed Jan 23 01:18:44 2019
New Revision: 351935

URL: http://llvm.org/viewvc/llvm-project?rev=351935&view=rev
Log:
[ARM][CGP] Check trunc type before replacing

In the last stage of type promotion, we replace any zext that uses a
new trunc with the operand of the trunc. This is okay when we only
allowed one type to be optimised, but now its the case that the trunc
maybe needed to produce a more narrow type than the one we were
optimising for. So we need to check this before doing the replacement.

Differential Revision: https://reviews.llvm.org/D57041

Modified:
    llvm/trunk/lib/Target/ARM/ARMCodeGenPrepare.cpp
    llvm/trunk/test/CodeGen/ARM/CGP/arm-cgp-casts.ll

Modified: llvm/trunk/lib/Target/ARM/ARMCodeGenPrepare.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMCodeGenPrepare.cpp?rev=351935&r1=351934&r2=351935&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMCodeGenPrepare.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMCodeGenPrepare.cpp Wed Jan 23 01:18:44 2019
@@ -113,7 +113,11 @@ class IRPromoter {
   SmallPtrSet<Value*, 8> Promoted;
   Module *M = nullptr;
   LLVMContext &Ctx;
+  // The type we promote to: always i32
   IntegerType *ExtTy = nullptr;
+  // The type of the value that the search began from, either i8 or i16.
+  // This defines the max range of the values that we allow in the promoted
+  // tree.
   IntegerType *OrigTy = nullptr;
   SmallPtrSetImpl<Value*> *Visited;
   SmallPtrSetImpl<Value*> *Sources;
@@ -326,7 +330,7 @@ bool ARMCodeGenPrepare::isSafeOverflow(I
   // - (255 >= 254) == (0xFFFFFFFF >= 254) == true
   //
   // To demonstrate why we can't handle increasing values:
-  // 
+  //
   // %add = add i8 %a, 2
   // %cmp = icmp ult i8 %add, 127
   //
@@ -604,7 +608,7 @@ void IRPromoter::PromoteTree() {
 
     if (!shouldPromote(I) || SafeToPromote->count(I) || NewInsts.count(I))
       continue;
-  
+
     assert(EnableDSP && "DSP intrinisc insertion not enabled!");
 
     // Replace unsafe instructions with appropriate intrinsic calls.
@@ -685,10 +689,10 @@ void IRPromoter::Cleanup() {
   // Some zexts will now have become redundant, along with their trunc
   // operands, so remove them
   for (auto V : *Visited) {
-    if (!isa<CastInst>(V))
+    if (!isa<ZExtInst>(V))
       continue;
 
-    auto ZExt = cast<CastInst>(V);
+    auto ZExt = cast<ZExtInst>(V);
     if (ZExt->getDestTy() != ExtTy)
       continue;
 
@@ -700,9 +704,11 @@ void IRPromoter::Cleanup() {
       continue;
     }
 
-    // For any truncs that we insert to handle zexts, we can replace the
-    // result of the zext with the input to the trunc.
-    if (NewInsts.count(Src) && isa<ZExtInst>(V) && isa<TruncInst>(Src)) {
+    // Unless they produce a value that is narrower than ExtTy, we can
+    // replace the result of the zext with the input of a newly inserted
+    // trunc.
+    if (NewInsts.count(Src) && isa<TruncInst>(Src) &&
+        Src->getType() == OrigTy) {
       auto *Trunc = cast<TruncInst>(Src);
       assert(Trunc->getOperand(0)->getType() == ExtTy &&
              "expected inserted trunc to be operating on i32");

Modified: llvm/trunk/test/CodeGen/ARM/CGP/arm-cgp-casts.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/CGP/arm-cgp-casts.ll?rev=351935&r1=351934&r2=351935&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/CGP/arm-cgp-casts.ll (original)
+++ llvm/trunk/test/CodeGen/ARM/CGP/arm-cgp-casts.ll Wed Jan 23 01:18:44 2019
@@ -588,3 +588,47 @@ cond.end:
   store i8 %cond, i8* @a, align 1
   ret void
 }
+
+; CHECK-LABEL: dont_replace_trunc_1
+; CHECK: cmp
+; CHECK: uxtb
+define void @dont_replace_trunc_1(i8* %a, i16* %b, i16* %c, i32* %d, i8* %e, i32* %f) {
+entry:
+  %0 = load i16, i16* %c, align 2
+  %1 = load i16, i16* %b, align 2
+  %conv = sext i16 %1 to i32
+  store i32 %conv, i32* %f, align 4
+  %2 = trunc i16 %1 to i8
+  %conv1 = and i8 %2, 1
+  store i8 %conv1, i8* %e, align 1
+  %3 = load i8, i8* %a, align 1
+  %narrow = mul nuw i8 %3, %conv1
+  %mul = zext i8 %narrow to i32
+  store i32 %mul, i32* %d, align 4
+  %4 = zext i8 %narrow to i16
+  %conv5 = or i16 %0, %4
+  %tobool = icmp eq i16 %conv5, 0
+  br i1 %tobool, label %if.end, label %for.cond
+
+for.cond:                                         ; preds = %entry, %for.cond
+  br label %for.cond
+
+if.end:                                           ; preds = %entry
+  ret void
+}
+
+; CHECK-LABEL: dont_replace_trunc_2
+; CHECK: cmp
+; CHECK: uxtb
+define i32 @dont_replace_trunc_2(i16* %a, i8* %b) {
+entry:
+  %0 = load i16, i16* %a, align 2
+  %cmp = icmp ugt i16 %0, 8
+  %narrow = select i1 %cmp, i16 %0, i16 0
+  %cond = trunc i16 %narrow to i8
+  %1 = load i8, i8* %b, align 1
+  %or = or i8 %1, %cond
+  store i8 %or, i8* %b, align 1
+  %conv5 = zext i8 %or to i32
+  ret i32 %conv5
+}




More information about the llvm-commits mailing list