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
116 lines
3.7 KiB
LLVM
116 lines
3.7 KiB
LLVM
; RUN: opt < %s -force-vector-width=4 -force-vector-interleave=1 -loop-vectorize -S | FileCheck %s
|
|
|
|
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
|
|
|
; CHECK-LABEL: @PR34687(
|
|
; CHECK: vector.body:
|
|
; CHECK-NEXT: [[INDEX:%.*]] = phi i32 [ 0, %vector.ph ], [ [[INDEX_NEXT:%.*]], %[[LATCH:.*]] ]
|
|
; CHECK-NEXT: [[VEC_PHI:%.*]] = phi <4 x i32> [ zeroinitializer, %vector.ph ], [ [[TMP17:%.*]], %[[LATCH]] ]
|
|
; CHECK: [[LATCH]]:
|
|
; CHECK: [[TMP13:%.*]] = and <4 x i32> [[VEC_PHI]], <i32 255, i32 255, i32 255, i32 255>
|
|
; CHECK-NEXT: [[TMP14:%.*]] = add <4 x i32> [[TMP13]], {{.*}}
|
|
; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 4
|
|
; CHECK: [[TMP16:%.*]] = trunc <4 x i32> [[TMP14]] to <4 x i8>
|
|
; CHECK-NEXT: [[TMP17]] = zext <4 x i8> [[TMP16]] to <4 x i32>
|
|
; CHECK-NEXT: br i1 {{.*}}, label %middle.block, label %vector.body
|
|
;
|
|
define i8 @PR34687(i1 %c, i32 %x, i32 %n) {
|
|
entry:
|
|
br label %for.body
|
|
|
|
for.body:
|
|
%i = phi i32 [ 0, %entry ], [ %i.next, %if.end ]
|
|
%r = phi i32 [ 0, %entry ], [ %r.next, %if.end ]
|
|
br i1 %c, label %if.then, label %if.end
|
|
|
|
if.then:
|
|
%tmp0 = sdiv i32 undef, undef
|
|
br label %if.end
|
|
|
|
if.end:
|
|
%tmp1 = and i32 %r, 255
|
|
%i.next = add nsw i32 %i, 1
|
|
%r.next = add nuw nsw i32 %tmp1, %x
|
|
%cond = icmp eq i32 %i.next, %n
|
|
br i1 %cond, label %for.end, label %for.body
|
|
|
|
for.end:
|
|
%tmp2 = phi i32 [ %r.next, %if.end ]
|
|
%tmp3 = trunc i32 %tmp2 to i8
|
|
ret i8 %tmp3
|
|
}
|
|
|
|
; CHECK-LABEL: @PR35734(
|
|
; CHECK: vector.ph:
|
|
; CHECK: [[TMP3:%.*]] = insertelement <4 x i32> zeroinitializer, i32 %y, i32 0
|
|
; CHECK-NEXT: br label %vector.body
|
|
; CHECK: vector.body:
|
|
; CHECK-NEXT: [[INDEX:%.*]] = phi i32 [ 0, %vector.ph ], [ [[INDEX_NEXT:%.*]], %vector.body ]
|
|
; CHECK-NEXT: [[VEC_PHI:%.*]] = phi <4 x i32> [ [[TMP3]], %vector.ph ], [ [[TMP9:%.*]], %vector.body ]
|
|
; CHECK: [[TMP5:%.*]] = and <4 x i32> [[VEC_PHI]], <i32 1, i32 1, i32 1, i32 1>
|
|
; CHECK-NEXT: [[TMP6:%.*]] = add <4 x i32> [[TMP5]], <i32 -1, i32 -1, i32 -1, i32 -1>
|
|
; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 4
|
|
; CHECK: [[TMP8:%.*]] = trunc <4 x i32> [[TMP6]] to <4 x i1>
|
|
; CHECK-NEXT: [[TMP9]] = sext <4 x i1> [[TMP8]] to <4 x i32>
|
|
; CHECK-NEXT: br i1 {{.*}}, label %middle.block, label %vector.body
|
|
;
|
|
define i32 @PR35734(i32 %x, i32 %y) {
|
|
entry:
|
|
br label %for.body
|
|
|
|
for.body:
|
|
%i = phi i32 [ %x, %entry ], [ %i.next, %for.body ]
|
|
%r = phi i32 [ %y, %entry ], [ %r.next, %for.body ]
|
|
%tmp0 = and i32 %r, 1
|
|
%r.next = add i32 %tmp0, -1
|
|
%i.next = add nsw i32 %i, 1
|
|
%cond = icmp sgt i32 %i, 77
|
|
br i1 %cond, label %for.end, label %for.body
|
|
|
|
for.end:
|
|
%tmp1 = phi i32 [ %r.next, %for.body ]
|
|
ret i32 %tmp1
|
|
}
|
|
|
|
define i32 @pr51794_signed_negative(i16 %iv.start, i32 %xor.start) {
|
|
; CHECK-LABEL: define {{.*}} @pr51794_signed_negative(
|
|
; CHECK-NOT: vector.body:
|
|
;
|
|
entry:
|
|
br label %loop
|
|
|
|
loop:
|
|
%xor.red = phi i32 [ %xor.start, %entry ], [ %xor, %loop ]
|
|
%iv = phi i16 [ %iv.start, %entry ], [ %iv.next, %loop ]
|
|
%iv.next = add i16 %iv, -1
|
|
%and = and i32 %xor.red, 1
|
|
%xor = xor i32 %and, -1
|
|
%tobool.not = icmp eq i16 %iv.next, 0
|
|
br i1 %tobool.not, label %exit, label %loop
|
|
|
|
exit:
|
|
%xor.lcssa = phi i32 [ %xor, %loop ]
|
|
ret i32 %xor.lcssa
|
|
}
|
|
|
|
define i32 @pr52485_signed_negative(i32 %xor.start) {
|
|
; CHECK-LABEL: define {{.*}} @pr52485_signed_negative(
|
|
; CHECK-NOT: vector.body:
|
|
;
|
|
entry:
|
|
br label %loop
|
|
|
|
loop:
|
|
%iv = phi i32 [ -23, %entry ], [ %iv.next, %loop ]
|
|
%xor.red = phi i32 [ %xor.start, %entry ], [ %xor, %loop ]
|
|
%and = and i32 %xor.red, 255
|
|
%xor = xor i32 %and, -9
|
|
%iv.next = add nuw nsw i32 %iv, 2
|
|
%cmp.not = icmp eq i32 %iv.next, -15
|
|
br i1 %cmp.not, label %exit, label %loop
|
|
|
|
exit:
|
|
%xor.lcssa = phi i32 [ %xor, %loop ]
|
|
ret i32 %xor.lcssa
|
|
}
|