[llvm] 0db7244 - [SCCP] Precommit some additional tests for integer ranges.

Florian Hahn via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 18 04:36:49 PDT 2020


Author: Florian Hahn
Date: 2020-03-18T11:34:04Z
New Revision: 0db7244295b15181991a793e99fe9a1a0b54a56d

URL: https://github.com/llvm/llvm-project/commit/0db7244295b15181991a793e99fe9a1a0b54a56d
DIFF: https://github.com/llvm/llvm-project/commit/0db7244295b15181991a793e99fe9a1a0b54a56d.diff

LOG: [SCCP] Precommit some additional tests for integer ranges.

Added: 
    llvm/test/Transforms/SCCP/binaryops-range-special-cases.ll
    llvm/test/Transforms/SCCP/ipsccp-range-crashes.ll

Modified: 
    llvm/test/Transforms/SCCP/range-and.ll

Removed: 
    


################################################################################
diff  --git a/llvm/test/Transforms/SCCP/binaryops-range-special-cases.ll b/llvm/test/Transforms/SCCP/binaryops-range-special-cases.ll
new file mode 100644
index 000000000000..a354ae0d4d5d
--- /dev/null
+++ b/llvm/test/Transforms/SCCP/binaryops-range-special-cases.ll
@@ -0,0 +1,103 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -ipsccp -S | FileCheck %s
+
+declare void @use(i1)
+define void @sdiv1_cmp_constants(i32 %x) {
+; CHECK-LABEL: @sdiv1_cmp_constants(
+; CHECK-NEXT:    [[D:%.*]] = sdiv i32 1, [[X:%.*]]
+; CHECK-NEXT:    [[C_0:%.*]] = icmp slt i32 0, [[D]]
+; CHECK-NEXT:    call void @use(i1 [[C_0]])
+; CHECK-NEXT:    [[C_1:%.*]] = icmp slt i32 1, [[D]]
+; CHECK-NEXT:    call void @use(i1 [[C_1]])
+; CHECK-NEXT:    [[C_2:%.*]] = icmp slt i32 2, [[D]]
+; CHECK-NEXT:    call void @use(i1 [[C_2]])
+; CHECK-NEXT:    [[C_3:%.*]] = icmp eq i32 1, [[D]]
+; CHECK-NEXT:    call void @use(i1 [[C_3]])
+; CHECK-NEXT:    [[C_4:%.*]] = icmp eq i32 0, [[D]]
+; CHECK-NEXT:    call void @use(i1 [[C_4]])
+; CHECK-NEXT:    [[C_5:%.*]] = icmp eq i32 2, [[D]]
+; CHECK-NEXT:    call void @use(i1 [[C_5]])
+; CHECK-NEXT:    ret void
+;
+  %d = sdiv i32 1, %x
+  %c.0 = icmp slt i32 0, %d
+  call void @use(i1 %c.0)
+  %c.1 = icmp slt i32 1, %d
+  call void @use(i1 %c.1)
+  %c.2 = icmp slt i32 2, %d
+  call void @use(i1 %c.2)
+
+  %c.3 = icmp eq i32 1, %d
+  call void @use(i1 %c.3)
+  %c.4 = icmp eq i32 0, %d
+  call void @use(i1 %c.4)
+  %c.5 = icmp eq i32 2, %d
+  call void @use(i1 %c.5)
+
+  ret void
+}
+
+define void @sdiv1_cmp_range_1(i32 %x, i1 %c) {
+; CHECK-LABEL: @sdiv1_cmp_range_1(
+; CHECK-NEXT:    br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
+; CHECK:       bb1:
+; CHECK-NEXT:    br label [[BB3:%.*]]
+; CHECK:       bb2:
+; CHECK-NEXT:    br label [[BB3]]
+; CHECK:       bb3:
+; CHECK-NEXT:    [[P:%.*]] = phi i32 [ 1, [[BB1]] ], [ 2, [[BB2]] ]
+; CHECK-NEXT:    [[D:%.*]] = sdiv i32 1, [[X:%.*]]
+; CHECK-NEXT:    [[C_0:%.*]] = icmp slt i32 [[P]], [[D]]
+; CHECK-NEXT:    call void @use(i1 [[C_0]])
+; CHECK-NEXT:    [[C_1:%.*]] = icmp eq i32 [[P]], [[D]]
+; CHECK-NEXT:    call void @use(i1 [[C_1]])
+; CHECK-NEXT:    ret void
+;
+  br i1 %c, label %bb1, label %bb2
+bb1:
+  br label %bb3
+bb2:
+  br label %bb3
+
+bb3:
+  %p = phi i32 [1, %bb1], [2, %bb2]
+  %d = sdiv i32 1, %x
+  %c.0 = icmp slt i32 %p, %d
+  call void @use(i1 %c.0)
+  %c.1 = icmp eq i32 %p, %d
+  call void @use(i1 %c.1)
+  ret void
+}
+
+
+define void @sdiv1_cmp_range_2(i32 %x, i1 %c) {
+; CHECK-LABEL: @sdiv1_cmp_range_2(
+; CHECK-NEXT:    br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
+; CHECK:       bb1:
+; CHECK-NEXT:    br label [[BB3:%.*]]
+; CHECK:       bb2:
+; CHECK-NEXT:    br label [[BB3]]
+; CHECK:       bb3:
+; CHECK-NEXT:    [[P:%.*]] = phi i32 [ 3, [[BB1]] ], [ 2, [[BB2]] ]
+; CHECK-NEXT:    [[D:%.*]] = sdiv i32 1, [[X:%.*]]
+; CHECK-NEXT:    [[C_0:%.*]] = icmp slt i32 [[P]], [[D]]
+; CHECK-NEXT:    call void @use(i1 [[C_0]])
+; CHECK-NEXT:    [[C_1:%.*]] = icmp eq i32 [[P]], [[D]]
+; CHECK-NEXT:    call void @use(i1 [[C_1]])
+; CHECK-NEXT:    ret void
+;
+  br i1 %c, label %bb1, label %bb2
+bb1:
+  br label %bb3
+bb2:
+  br label %bb3
+
+bb3:
+  %p = phi i32 [3, %bb1], [2, %bb2]
+  %d = sdiv i32 1, %x
+  %c.0 = icmp slt i32 %p, %d
+  call void @use(i1 %c.0)
+  %c.1 = icmp eq i32 %p, %d
+  call void @use(i1 %c.1)
+  ret void
+}

diff  --git a/llvm/test/Transforms/SCCP/ipsccp-range-crashes.ll b/llvm/test/Transforms/SCCP/ipsccp-range-crashes.ll
new file mode 100644
index 000000000000..117eed78064e
--- /dev/null
+++ b/llvm/test/Transforms/SCCP/ipsccp-range-crashes.ll
@@ -0,0 +1,195 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -ipsccp -S %s | FileCheck %s
+
+; A few test cases exposing crashes with the initial range implementation.
+
+ at global.2 = external dso_local unnamed_addr constant [25 x i8], align 1
+ at global = internal local_unnamed_addr global i32 0, align 4
+ at global.3 = internal local_unnamed_addr global i32 0, align 4
+
+define void @main(i8** %arg) {
+; CHECK-LABEL: @main(
+; CHECK-NEXT:  bb:
+; CHECK-NEXT:    [[TMP:%.*]] = getelementptr inbounds i8*, i8** [[ARG:%.*]], i64 undef
+; CHECK-NEXT:    [[TMP1:%.*]] = load i8*, i8** [[TMP]], align 8
+; CHECK-NEXT:    [[TMP2:%.*]] = load i8, i8* [[TMP1]], align 1
+; CHECK-NEXT:    [[TMP3:%.*]] = sext i8 [[TMP2]] to i32
+; CHECK-NEXT:    [[TMP4:%.*]] = icmp ne i32 [[TMP3]], 45
+; CHECK-NEXT:    [[TMP5:%.*]] = select i1 [[TMP4]], i32 2, i32 4
+; CHECK-NEXT:    ret void
+;
+bb:
+  %tmp = getelementptr inbounds i8*, i8** %arg, i64 undef
+  %tmp1 = load i8*, i8** %tmp, align 8
+  %tmp2 = load i8, i8* %tmp1, align 1
+  %tmp3 = sext i8 %tmp2 to i32
+  %tmp4 = icmp ne i32 %tmp3, 45
+  %tmp5 = select i1 %tmp4, i32 2, i32 4
+  ret void
+}
+
+define void @ham() local_unnamed_addr {
+; CHECK-LABEL: @ham(
+; CHECK-NEXT:  bb:
+; CHECK-NEXT:    br label [[BB1:%.*]]
+; CHECK:       bb1:
+; CHECK-NEXT:    [[TMP:%.*]] = icmp slt i32 undef, 40
+; CHECK-NEXT:    br i1 [[TMP]], label [[BB2:%.*]], label [[BB4:%.*]]
+; CHECK:       bb2:
+; CHECK-NEXT:    br label [[BB7:%.*]]
+; CHECK:       bb3:
+; CHECK-NEXT:    br label [[BB4]]
+; CHECK:       bb4:
+; CHECK-NEXT:    [[TMP5:%.*]] = phi i64 [ 0, [[BB1]] ], [ 15, [[BB3:%.*]] ]
+; CHECK-NEXT:    [[TMP6:%.*]] = add i64 [[TMP5]], add (i64 xor (i64 ptrtoint ([25 x i8]* @global.2 to i64), i64 -1), i64 1)
+; CHECK-NEXT:    unreachable
+; CHECK:       bb7:
+; CHECK-NEXT:    br label [[BB3]]
+;
+bb:
+  br label %bb1
+
+bb1:                                              ; preds = %bb
+  %tmp = icmp slt i32 undef, 40
+  br i1 %tmp, label %bb2, label %bb4
+
+bb2:                                              ; preds = %bb1
+  br label %bb7
+
+bb3:                                              ; preds = %bb7
+  br label %bb4
+
+bb4:                                              ; preds = %bb3, %bb1
+  %tmp5 = phi i64 [ 0, %bb1 ], [ %tmp10, %bb3 ]
+  %tmp6 = add i64 %tmp5, add (i64 xor (i64 ptrtoint ([25 x i8]* @global.2 to i64), i64 -1), i64 1)
+  unreachable
+
+bb7:                                              ; preds = %bb2
+  %tmp8 = add i64 0, 15
+  %tmp9 = add i64 %tmp8, 0
+  %tmp10 = add i64 %tmp9, 0
+  br label %bb3
+}
+
+declare i32 @barney.4()
+
+define void @wobble() {
+; CHECK-LABEL: @wobble(
+; CHECK-NEXT:  bb:
+; CHECK-NEXT:    [[TMP:%.*]] = load i32, i32* @global, align 4
+; CHECK-NEXT:    store i32 [[TMP]], i32* @global.3, align 4
+; CHECK-NEXT:    ret void
+;
+bb:
+  %tmp = load i32, i32* @global, align 4
+  store i32 %tmp, i32* @global.3, align 4
+  ret void
+}
+
+define i32 @wobble.5(i32 %arg) {
+bb:
+  %tmp = load i32, i32* @global.3, align 4
+  %tmp1 = sdiv i32 0, %tmp
+  ret i32 %tmp1
+}
+
+define void @eggs() {
+; CHECK-LABEL: @eggs(
+; CHECK-NEXT:  bb:
+; CHECK-NEXT:    br label [[BB1:%.*]]
+; CHECK:       bb1:
+; CHECK-NEXT:    [[TMP:%.*]] = phi i32 [ 0, [[BB:%.*]] ], [ [[TMP2:%.*]], [[BB1]] ]
+; CHECK-NEXT:    [[TMP2]] = add nsw i32 [[TMP]], 1
+; CHECK-NEXT:    [[TMP3:%.*]] = call i32 @barney.4()
+; CHECK-NEXT:    [[TMP4:%.*]] = icmp eq i32 [[TMP3]], 1
+; CHECK-NEXT:    br i1 [[TMP4]], label [[BB1]], label [[BB5:%.*]]
+; CHECK:       bb5:
+; CHECK-NEXT:    store i32 [[TMP2]], i32* @global, align 4
+; CHECK-NEXT:    ret void
+;
+bb:
+  br label %bb1
+
+bb1:                                              ; preds = %bb1, %bb
+  %tmp = phi i32 [ 0, %bb ], [ %tmp2, %bb1 ]
+  %tmp2 = add nsw i32 %tmp, 1
+  %tmp3 = call i32 @barney.4()
+  %tmp4 = icmp eq i32 %tmp3, 1
+  br i1 %tmp4, label %bb1, label %bb5
+
+bb5:                                              ; preds = %bb1
+  store i32 %tmp2, i32* @global, align 4
+  ret void
+}
+
+declare i32* @bar(i32) local_unnamed_addr #3
+
+; Function Attrs: nounwind ssp uwtable
+define { i8, i32* } @struct_crash(i32 %BitWidth) local_unnamed_addr #0 align 2 {
+; CHECK-LABEL: @struct_crash(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    switch i32 [[BITWIDTH:%.*]], label [[IF_END:%.*]] [
+; CHECK-NEXT:    i32 1, label [[CLEANUP:%.*]]
+; CHECK-NEXT:    i32 8, label [[SW_BB1_I:%.*]]
+; CHECK-NEXT:    ]
+; CHECK:       sw.bb1.i:
+; CHECK-NEXT:    br label [[CLEANUP]]
+; CHECK:       if.end:
+; CHECK-NEXT:    [[CALL_I:%.*]] = tail call i32* @bar(i32 [[BITWIDTH]])
+; CHECK-NEXT:    br label [[CLEANUP]]
+; CHECK:       cleanup:
+; CHECK-NEXT:    [[V1:%.*]] = phi i32* [ [[CALL_I]], [[IF_END]] ], [ null, [[SW_BB1_I]] ], [ null, [[ENTRY:%.*]] ]
+; CHECK-NEXT:    [[V2:%.*]] = phi i8 [ 0, [[IF_END]] ], [ 3, [[SW_BB1_I]] ], [ 2, [[ENTRY]] ]
+; CHECK-NEXT:    [[DOTFCA_0_INSERT:%.*]] = insertvalue { i8, i32* } undef, i8 [[V2]], 0
+; CHECK-NEXT:    [[DOTFCA_1_INSERT:%.*]] = insertvalue { i8, i32* } [[DOTFCA_0_INSERT]], i32* [[V1]], 1
+; CHECK-NEXT:    ret { i8, i32* } [[DOTFCA_1_INSERT]]
+;
+entry:
+  switch i32 %BitWidth, label %if.end [
+  i32 1, label %cleanup
+  i32 8, label %sw.bb1.i
+  ]
+
+sw.bb1.i:                                         ; preds = %entry
+  br label %cleanup
+
+if.end:                                           ; preds = %entry
+  %call.i = tail call i32* @bar(i32 %BitWidth)
+  br label %cleanup
+
+cleanup:                                          ; preds = %entry, %sw.bb1.i, %sw.bb2.i, %sw.bb3.i, %sw.bb4.i, %sw.bb5.i, %if.end
+  %v1 = phi i32* [ %call.i, %if.end ], [ null, %sw.bb1.i ], [ null, %entry ]
+  %v2 = phi i8 [ 0, %if.end ], [ 3, %sw.bb1.i ], [ 2, %entry ]
+  %.fca.0.insert = insertvalue { i8, i32* } undef, i8 %v2, 0
+  %.fca.1.insert = insertvalue { i8, i32* } %.fca.0.insert, i32* %v1, 1
+  ret { i8, i32* } %.fca.1.insert
+}
+
+define i64 @crash_ctpop(i1 %cond, i32* %addr) {
+; CHECK-LABEL: @crash_ctpop(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
+; CHECK:       if.then:
+; CHECK-NEXT:    ret i64 0
+; CHECK:       if.else:
+; CHECK-NEXT:    [[LV:%.*]] = load i32, i32* [[ADDR:%.*]], align 8
+; CHECK-NEXT:    [[ANDV:%.*]] = and i32 [[LV]], 16777215
+; CHECK-NEXT:    [[TRUNCV:%.*]] = zext i32 [[ANDV]] to i64
+; CHECK-NEXT:    [[RES:%.*]] = tail call i64 @llvm.ctpop.i64(i64 [[TRUNCV]])
+; CHECK-NEXT:    ret i64 [[RES]]
+;
+entry:
+  br i1 %cond, label %if.then, label %if.else
+
+if.then:                                        ; preds = %entry
+  ret i64 0
+
+if.else:                                        ; preds = %entry
+  %lv = load i32, i32* %addr, align 8
+  %andv = and i32 %lv, 16777215
+  %truncv = zext i32 %andv to i64
+  %res = tail call i64 @llvm.ctpop.i64(i64 %truncv)
+  ret i64 %res
+}
+
+declare i64 @llvm.ctpop.i64(i64)

diff  --git a/llvm/test/Transforms/SCCP/range-and.ll b/llvm/test/Transforms/SCCP/range-and.ll
index 1ca089f4aa8c..e948274dd8f1 100644
--- a/llvm/test/Transforms/SCCP/range-and.ll
+++ b/llvm/test/Transforms/SCCP/range-and.ll
@@ -1,7 +1,42 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --verbose
 ; RUN: opt -S -sccp %s | FileCheck %s
 
-; Test case for PR44949.
+declare void @use(i1)
+
+define void @and_range_limit(i64 %a) {
+; CHECK-LABEL: @and_range_limit(
+; CHECK-NEXT:    [[R:%.*]] = and i64 [[A:%.*]], 255
+; CHECK-NEXT:    [[C_0:%.*]] = icmp slt i64 [[R]], 15
+; CHECK-NEXT:    call void @use(i1 [[C_0]])
+; CHECK-NEXT:    [[C_1:%.*]] = icmp slt i64 [[R]], 256
+; CHECK-NEXT:    call void @use(i1 [[C_1]])
+; CHECK-NEXT:    [[C_2:%.*]] = icmp eq i64 [[R]], 100
+; CHECK-NEXT:    call void @use(i1 [[C_2]])
+; CHECK-NEXT:    [[C_3:%.*]] = icmp eq i64 [[R]], 300
+; CHECK-NEXT:    call void @use(i1 [[C_3]])
+; CHECK-NEXT:    [[C_4:%.*]] = icmp ne i64 [[R]], 100
+; CHECK-NEXT:    call void @use(i1 [[C_4]])
+; CHECK-NEXT:    [[C_5:%.*]] = icmp ne i64 [[R]], 300
+; CHECK-NEXT:    call void @use(i1 [[C_5]])
+; CHECK-NEXT:    ret void
+;
+  %r = and i64 %a, 255
+  %c.0 = icmp slt i64 %r, 15
+  call void @use(i1 %c.0)
+  %c.1 = icmp slt i64 %r, 256
+  call void @use(i1 %c.1)
+  %c.2 = icmp eq i64 %r, 100
+  call void @use(i1 %c.2)
+  %c.3 = icmp eq i64 %r, 300
+  call void @use(i1 %c.3)
+  %c.4 = icmp ne i64 %r, 100
+  call void @use(i1 %c.4)
+  %c.5 = icmp ne i64 %r, 300
+  call void @use(i1 %c.5)
+  ret void
+}
+
+; Below are test cases for PR44949.
 
 ; We can remove `%res = and i64 %p, 255`, because %r = 0 and we can eliminate
 ; %p as well.


        


More information about the llvm-commits mailing list