I stumbled over this while trying to improve our exit count work. These expressions are equivalent for complementary signed/unsigned ext and min/max (including umin_seq), but they are not canonicalized and SCEV cannot recognize them as the same. The benefit of this canonicalization is that SCEV can prove some new equivalences which it coudln't prove because of different forms. There is 1 test where trip count seems pessimized, I could not directly figure out why, but it just seems an unrelated issue that we can fix. Other changes seem neutral or positive to me. Differential Revision: https://reviews.llvm.org/D141481 Reviewed By: nikic
156 lines
7.8 KiB
LLVM
156 lines
7.8 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py
|
|
; RUN: opt -S -disable-output "-passes=print<scalar-evolution>" < %s 2>&1 | FileCheck %s
|
|
|
|
; TODO: Make sure that zext(umin(x, y)) has same SCEV as umin(zext(x), zext(y)).
|
|
; Equality proof: https://alive2.llvm.org/ce/z/vdsvmp
|
|
define i1 @test_umin(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: 'test_umin'
|
|
; CHECK-NEXT: Classifying expressions for: @test_umin
|
|
; CHECK-NEXT: %umin_x_y = select i1 %cmp_x_y, i32 %x, i32 %y
|
|
; CHECK-NEXT: --> (%x umin %y) U: full-set S: full-set
|
|
; CHECK-NEXT: %zext_umin_x_y = zext i32 %umin_x_y to i64
|
|
; CHECK-NEXT: --> ((zext i32 %x to i64) umin (zext i32 %y to i64)) U: [0,4294967296) S: [0,4294967296)
|
|
; CHECK-NEXT: %zext_x = zext i32 %x to i64
|
|
; CHECK-NEXT: --> (zext i32 %x to i64) U: [0,4294967296) S: [0,4294967296)
|
|
; CHECK-NEXT: %zext_y = zext i32 %y to i64
|
|
; CHECK-NEXT: --> (zext i32 %y to i64) U: [0,4294967296) S: [0,4294967296)
|
|
; CHECK-NEXT: %umin_zext_x_zext_y = select i1 %cmp_zext_x_zext_y, i64 %zext_x, i64 %zext_y
|
|
; CHECK-NEXT: --> ((zext i32 %x to i64) umin (zext i32 %y to i64)) U: [0,4294967296) S: [0,4294967296)
|
|
; CHECK-NEXT: Determining loop execution counts for: @test_umin
|
|
;
|
|
%cmp_x_y = icmp ult i32 %x, %y
|
|
%umin_x_y = select i1 %cmp_x_y, i32 %x, i32 %y
|
|
%zext_umin_x_y = zext i32 %umin_x_y to i64
|
|
|
|
%zext_x = zext i32 %x to i64
|
|
%zext_y = zext i32 %y to i64
|
|
%cmp_zext_x_zext_y = icmp ult i64 %zext_x, %zext_y
|
|
%umin_zext_x_zext_y = select i1 %cmp_zext_x_zext_y, i64 %zext_x, i64 %zext_y
|
|
|
|
%they_are_same = icmp eq i64 %zext_umin_x_y, %umin_zext_x_zext_y
|
|
ret i1 %they_are_same
|
|
}
|
|
|
|
; TODO: Make sure that zext(umax(x, y)) has same SCEV as umax(zext(x), zext(y)).
|
|
; Equality proof: https://alive2.llvm.org/ce/z/5JHgxZ
|
|
define i1 @test_umax(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: 'test_umax'
|
|
; CHECK-NEXT: Classifying expressions for: @test_umax
|
|
; CHECK-NEXT: %umax_x_y = select i1 %cmp_x_y, i32 %y, i32 %x
|
|
; CHECK-NEXT: --> (%x umax %y) U: full-set S: full-set
|
|
; CHECK-NEXT: %zext_umax_x_y = zext i32 %umax_x_y to i64
|
|
; CHECK-NEXT: --> ((zext i32 %x to i64) umax (zext i32 %y to i64)) U: [0,4294967296) S: [0,4294967296)
|
|
; CHECK-NEXT: %zext_x = zext i32 %x to i64
|
|
; CHECK-NEXT: --> (zext i32 %x to i64) U: [0,4294967296) S: [0,4294967296)
|
|
; CHECK-NEXT: %zext_y = zext i32 %y to i64
|
|
; CHECK-NEXT: --> (zext i32 %y to i64) U: [0,4294967296) S: [0,4294967296)
|
|
; CHECK-NEXT: %umax_zext_x_zext_y = select i1 %cmp_zext_x_zext_y, i64 %zext_y, i64 %zext_x
|
|
; CHECK-NEXT: --> ((zext i32 %x to i64) umax (zext i32 %y to i64)) U: [0,4294967296) S: [0,4294967296)
|
|
; CHECK-NEXT: Determining loop execution counts for: @test_umax
|
|
;
|
|
%cmp_x_y = icmp ult i32 %x, %y
|
|
%umax_x_y = select i1 %cmp_x_y, i32 %y, i32 %x
|
|
%zext_umax_x_y = zext i32 %umax_x_y to i64
|
|
|
|
%zext_x = zext i32 %x to i64
|
|
%zext_y = zext i32 %y to i64
|
|
%cmp_zext_x_zext_y = icmp ult i64 %zext_x, %zext_y
|
|
%umax_zext_x_zext_y = select i1 %cmp_zext_x_zext_y, i64 %zext_y, i64 %zext_x
|
|
|
|
%they_are_same = icmp eq i64 %zext_umax_x_y, %umax_zext_x_zext_y
|
|
ret i1 %they_are_same
|
|
}
|
|
|
|
; TODO: Make sure that sext(smin(x, y)) has same SCEV as smin(sext(x), sext(y)).
|
|
; Equality proof: https://alive2.llvm.org/ce/z/HhYHzR
|
|
define i1 @test_smin(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: 'test_smin'
|
|
; CHECK-NEXT: Classifying expressions for: @test_smin
|
|
; CHECK-NEXT: %smin_x_y = select i1 %cmp_x_y, i32 %x, i32 %y
|
|
; CHECK-NEXT: --> (%x smin %y) U: full-set S: full-set
|
|
; CHECK-NEXT: %sext_smin_x_y = sext i32 %smin_x_y to i64
|
|
; CHECK-NEXT: --> ((sext i32 %x to i64) smin (sext i32 %y to i64)) U: [-2147483648,2147483648) S: [-2147483648,2147483648)
|
|
; CHECK-NEXT: %sext_x = sext i32 %x to i64
|
|
; CHECK-NEXT: --> (sext i32 %x to i64) U: [-2147483648,2147483648) S: [-2147483648,2147483648)
|
|
; CHECK-NEXT: %sext_y = sext i32 %y to i64
|
|
; CHECK-NEXT: --> (sext i32 %y to i64) U: [-2147483648,2147483648) S: [-2147483648,2147483648)
|
|
; CHECK-NEXT: %smin_sext_x_sext_y = select i1 %cmp_sext_x_sext_y, i64 %sext_x, i64 %sext_y
|
|
; CHECK-NEXT: --> ((sext i32 %x to i64) smin (sext i32 %y to i64)) U: [-2147483648,2147483648) S: [-2147483648,2147483648)
|
|
; CHECK-NEXT: Determining loop execution counts for: @test_smin
|
|
;
|
|
%cmp_x_y = icmp slt i32 %x, %y
|
|
%smin_x_y = select i1 %cmp_x_y, i32 %x, i32 %y
|
|
%sext_smin_x_y = sext i32 %smin_x_y to i64
|
|
|
|
%sext_x = sext i32 %x to i64
|
|
%sext_y = sext i32 %y to i64
|
|
%cmp_sext_x_sext_y = icmp slt i64 %sext_x, %sext_y
|
|
%smin_sext_x_sext_y = select i1 %cmp_sext_x_sext_y, i64 %sext_x, i64 %sext_y
|
|
|
|
%they_are_same = icmp eq i64 %sext_smin_x_y, %smin_sext_x_sext_y
|
|
ret i1 %they_are_same
|
|
}
|
|
|
|
; TODO: Make sure that sext(smax(x, y)) has same SCEV as smax(sext(x), sext(y)).
|
|
; Equality proof: https://alive2.llvm.org/ce/z/uou_u-
|
|
define i1 @test_smax(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: 'test_smax'
|
|
; CHECK-NEXT: Classifying expressions for: @test_smax
|
|
; CHECK-NEXT: %smax_x_y = select i1 %cmp_x_y, i32 %y, i32 %x
|
|
; CHECK-NEXT: --> (%x smax %y) U: full-set S: full-set
|
|
; CHECK-NEXT: %sext_smax_x_y = sext i32 %smax_x_y to i64
|
|
; CHECK-NEXT: --> ((sext i32 %x to i64) smax (sext i32 %y to i64)) U: [-2147483648,2147483648) S: [-2147483648,2147483648)
|
|
; CHECK-NEXT: %sext_x = sext i32 %x to i64
|
|
; CHECK-NEXT: --> (sext i32 %x to i64) U: [-2147483648,2147483648) S: [-2147483648,2147483648)
|
|
; CHECK-NEXT: %sext_y = sext i32 %y to i64
|
|
; CHECK-NEXT: --> (sext i32 %y to i64) U: [-2147483648,2147483648) S: [-2147483648,2147483648)
|
|
; CHECK-NEXT: %smax_sext_x_sext_y = select i1 %cmp_sext_x_sext_y, i64 %sext_y, i64 %sext_x
|
|
; CHECK-NEXT: --> ((sext i32 %x to i64) smax (sext i32 %y to i64)) U: [-2147483648,2147483648) S: [-2147483648,2147483648)
|
|
; CHECK-NEXT: Determining loop execution counts for: @test_smax
|
|
;
|
|
%cmp_x_y = icmp slt i32 %x, %y
|
|
%smax_x_y = select i1 %cmp_x_y, i32 %y, i32 %x
|
|
%sext_smax_x_y = sext i32 %smax_x_y to i64
|
|
|
|
%sext_x = sext i32 %x to i64
|
|
%sext_y = sext i32 %y to i64
|
|
%cmp_sext_x_sext_y = icmp slt i64 %sext_x, %sext_y
|
|
%smax_sext_x_sext_y = select i1 %cmp_sext_x_sext_y, i64 %sext_y, i64 %sext_x
|
|
|
|
%they_are_same = icmp eq i64 %sext_smax_x_y, %smax_sext_x_sext_y
|
|
ret i1 %they_are_same
|
|
}
|
|
|
|
; TODO: Make sure that zext(umin_seq(x, y)) has same SCEV as umin_seq(zext(x), zext(y)).
|
|
; Equality proof: https://alive2.llvm.org/ce/z/X8kaNx
|
|
define i1 @test_umin_seq(i1 %x, i1 %y) {
|
|
; CHECK-LABEL: 'test_umin_seq'
|
|
; CHECK-NEXT: Classifying expressions for: @test_umin_seq
|
|
; CHECK-NEXT: %x_umin_seq_y = select i1 %x, i1 %y, i1 false
|
|
; CHECK-NEXT: --> (%x umin_seq %y) U: full-set S: full-set
|
|
; CHECK-NEXT: %zext_x_umin_seq_y = zext i1 %x_umin_seq_y to i64
|
|
; CHECK-NEXT: --> ((zext i1 %x to i64) umin_seq (zext i1 %y to i64)) U: [0,2) S: [0,2)
|
|
; CHECK-NEXT: %zext_x = zext i1 %x to i64
|
|
; CHECK-NEXT: --> (zext i1 %x to i64) U: [0,2) S: [0,2)
|
|
; CHECK-NEXT: %zext_y = zext i1 %y to i64
|
|
; CHECK-NEXT: --> (zext i1 %y to i64) U: [0,2) S: [0,2)
|
|
; CHECK-NEXT: %umin_zext_x_zext_y = select i1 %cmp_zext_x_zext_y, i64 %zext_x, i64 %zext_y
|
|
; CHECK-NEXT: --> ((zext i1 %x to i64) umin (zext i1 %y to i64)) U: [0,2) S: [0,2)
|
|
; CHECK-NEXT: %umin_seq_zext_x_xext_y = select i1 %zext_x_is_0, i64 0, i64 %umin_zext_x_zext_y
|
|
; CHECK-NEXT: --> ((zext i1 %x to i64) umin_seq (zext i1 %y to i64)) U: [0,2) S: [0,2)
|
|
; CHECK-NEXT: Determining loop execution counts for: @test_umin_seq
|
|
;
|
|
%x_umin_seq_y = select i1 %x, i1 %y, i1 false
|
|
%zext_x_umin_seq_y = zext i1 %x_umin_seq_y to i64
|
|
|
|
%zext_x = zext i1 %x to i64
|
|
%zext_y = zext i1 %y to i64
|
|
%zext_x_is_0 = icmp eq i64 %zext_x, 0
|
|
%cmp_zext_x_zext_y = icmp ult i64 %zext_x, %zext_y
|
|
%umin_zext_x_zext_y = select i1 %cmp_zext_x_zext_y, i64 %zext_x, i64 %zext_y
|
|
%umin_seq_zext_x_xext_y = select i1 %zext_x_is_0, i64 0, i64 %umin_zext_x_zext_y
|
|
|
|
%they_are_same = icmp eq i64 %zext_x_umin_seq_y, %umin_seq_zext_x_xext_y
|
|
ret i1 %they_are_same
|
|
}
|