[llvm] 112c1c3 - [IVDescriptor] Make sure the sign is included for negative extension.

Florian Hahn via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 15 05:13:33 PST 2021


Author: Florian Hahn
Date: 2021-11-15T13:12:57Z
New Revision: 112c1c346a61459238d286fe6a649842fcbcd7ce

URL: https://github.com/llvm/llvm-project/commit/112c1c346a61459238d286fe6a649842fcbcd7ce
DIFF: https://github.com/llvm/llvm-project/commit/112c1c346a61459238d286fe6a649842fcbcd7ce.diff

LOG: [IVDescriptor] Make sure the sign is included for negative extension.

At the moment, computeRecurrenceType does not include any sign bits in
the maximum bit width. If the value can be negative, this means the sign
bit will be missing and the sext won't properly extend the value.

If the value can be negative, increment the bitwidth by one to make sure
there is at least one sign bit in the result value.

Note that the increment is also needed *if* the value is *known* to be
negative, as a sign bit needs to be preserved for the sext to work.

Note that this at the moment prevents vectorization, because the
analysis computes i1 as type for the recurrence when looking through the
AND in lookThroughAnd.

Fixes PR51794, PR52485.

Reviewed By: spatel

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

Added: 
    

Modified: 
    llvm/lib/Analysis/IVDescriptors.cpp
    llvm/test/Transforms/LoopVectorize/reduction-small-size.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/IVDescriptors.cpp b/llvm/lib/Analysis/IVDescriptors.cpp
index 4546e3f0ebeb..d430f1ae83f0 100644
--- a/llvm/lib/Analysis/IVDescriptors.cpp
+++ b/llvm/lib/Analysis/IVDescriptors.cpp
@@ -146,12 +146,9 @@ static std::pair<Type *, bool> computeRecurrenceType(Instruction *Exit,
       // meaning that we will use sext instructions instead of zext
       // instructions to restore the original type.
       IsSigned = true;
-      if (!Bits.isNegative())
-        // If the value is not known to be negative, we don't known what the
-        // upper bit is, and therefore, we don't know what kind of extend we
-        // will need. In this case, just increase the bit width by one bit and
-        // use sext.
-        ++MaxBitWidth;
+      // Make sure at at least one sign bit is included in the result, so it
+      // will get properly sign-extended.
+      ++MaxBitWidth;
     }
   }
   if (!isPowerOf2_64(MaxBitWidth))

diff  --git a/llvm/test/Transforms/LoopVectorize/reduction-small-size.ll b/llvm/test/Transforms/LoopVectorize/reduction-small-size.ll
index 922f55ccb842..ef5e63252ac5 100644
--- a/llvm/test/Transforms/LoopVectorize/reduction-small-size.ll
+++ b/llvm/test/Transforms/LoopVectorize/reduction-small-size.ll
@@ -74,18 +74,7 @@ for.end:
 
 define i32 @pr51794_signed_negative(i16 %iv.start, i32 %xor.start) {
 ; CHECK-LABEL: define {{.*}} @pr51794_signed_negative(
-; CHECK:   [[XOR_START:%.+]] = insertelement <4 x i32> zeroinitializer, i32 %xor.start, i32 0
-; CHECK-LABEL: vector.body:
-; CHECK:         [[XOR_RED:%.+]] = phi <4 x i32> [ [[XOR_START]], %vector.ph ], [ [[XOR_SEXT:%.+]], %vector.body ]
-; CHECK:         [[AND:%.+]] = and <4 x i32> [[XOR_RED]], <i32 1, i32 1, i32 1, i32 1>
-; CHECK-NEXT:    [[XOR:%.+]] = xor <4 x i32> [[AND]], <i32 -1, i32 -1, i32 -1, i32 -1>
-; CHECK:         [[XOR_TRUNC:%.+]] = trunc <4 x i32> [[XOR]] to <4 x i1>
-; CHECK-NEXT:    [[XOR_SEXT]] = sext <4 x i1> [[XOR_TRUNC]] to <4 x i32>
-;
-; CHECK-LABEL: middle.block:
-; CHECK-NEXT:   [[RES_TRUNC:%.+]] = trunc <4 x i32> [[XOR_SEXT]] to <4 x i1>
-; CHECK-NEXT:   [[RES_RED:%.+]]  = call i1 @llvm.vector.reduce.xor.v4i1(<4 x i1> [[RES_TRUNC]])
-; CHECK-NEXT:   sext i1 [[RES_RED]] to i32
+; CHECK-NOT: vector.body:
 ;
 entry:
   br label %loop
@@ -106,18 +95,7 @@ exit:
 
 define i32 @pr52485_signed_negative(i32 %xor.start) {
 ; CHECK-LABEL: define {{.*}} @pr52485_signed_negative(
-; CHECK:   [[XOR_START:%.+]] = insertelement <4 x i32> zeroinitializer, i32 %xor.start, i32 0
-; CHECK-LABEL: vector.body:
-; CHECK:         [[XOR_RED:%.+]] = phi <4 x i32> [ [[XOR_START]], %vector.ph ], [ [[XOR_SEXT:%.+]], %vector.body ]
-; CHECK:         [[AND:%.+]] = and <4 x i32> [[XOR_RED]], <i32 255, i32 255, i32 255, i32 255>
-; CHECK-NEXT:    [[XOR:%.+]] = xor <4 x i32> [[AND]], <i32 -9, i32 -9, i32 -9, i32 -9>
-; CHECK:         [[XOR_TRUNC:%.+]] = trunc <4 x i32> [[XOR]] to <4 x i8>
-; CHECK-NEXT:    [[XOR_SEXT]] = sext <4 x i8> [[XOR_TRUNC]] to <4 x i32>
-;
-; CHECK-LABEL: middle.block:
-; CHECK-NEXT:   [[RES_TRUNC:%.+]] = trunc <4 x i32> [[XOR_SEXT]] to <4 x i8>
-; CHECK-NEXT:   [[RES_RED:%.+]]  = call i8 @llvm.vector.reduce.xor.v4i8(<4 x i8> [[RES_TRUNC]])
-; CHECK-NEXT:   sext i8 [[RES_RED]] to i32
+; CHECK-NOT: vector.body:
 ;
 entry:
   br label %loop


        


More information about the llvm-commits mailing list