[InstCombine] add test for assume in block with unreachable (PR47416); NFC

This commit is contained in:
Sanjay Patel 2020-09-04 11:14:48 -04:00
parent b3e139444f
commit c5d6b2b7e5
1 changed files with 66 additions and 57 deletions

View File

@ -1,66 +1,56 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -instcombine -S | FileCheck %s
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
define i32 @foo1(i32* %a) #0 {
; CHECK-LABEL: @foo1(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[A:%.*]], align 32
; CHECK-NEXT: [[PTRINT:%.*]] = ptrtoint i32* [[A]] to i64
; CHECK-NEXT: [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], 31
; CHECK-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0
; CHECK-NEXT: tail call void @llvm.assume(i1 [[MASKCOND]])
; CHECK-NEXT: ret i32 [[TMP0]]
;
entry:
%0 = load i32, i32* %a, align 4
declare void @llvm.assume(i1) #1
; Check that the alignment has been upgraded and that the assume has not
; been removed:
define i32 @foo1(i32* %a) #0 {
; CHECK-LABEL: @foo1(
; CHECK-NEXT: [[T0:%.*]] = load i32, i32* [[A:%.*]], align 32
; CHECK-NEXT: [[PTRINT:%.*]] = ptrtoint i32* [[A]] to i64
; CHECK-NEXT: [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], 31
; CHECK-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0
; CHECK-NEXT: tail call void @llvm.assume(i1 [[MASKCOND]])
; CHECK-NEXT: ret i32 [[T0]]
;
%t0 = load i32, i32* %a, align 4
%ptrint = ptrtoint i32* %a to i64
%maskedptr = and i64 %ptrint, 31
%maskcond = icmp eq i64 %maskedptr, 0
tail call void @llvm.assume(i1 %maskcond)
ret i32 %0
ret i32 %t0
}
; Same check as in @foo1, but make sure it works if the assume is first too.
define i32 @foo2(i32* %a) #0 {
; CHECK-LABEL: @foo2(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[PTRINT:%.*]] = ptrtoint i32* [[A:%.*]] to i64
; CHECK-NEXT: [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], 31
; CHECK-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0
; CHECK-NEXT: tail call void @llvm.assume(i1 [[MASKCOND]])
; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[A]], align 32
; CHECK-NEXT: ret i32 [[TMP0]]
; CHECK-NEXT: [[T0:%.*]] = load i32, i32* [[A]], align 32
; CHECK-NEXT: ret i32 [[T0]]
;
entry:
; Same check as in @foo1, but make sure it works if the assume is first too.
%ptrint = ptrtoint i32* %a to i64
%maskedptr = and i64 %ptrint, 31
%maskcond = icmp eq i64 %maskedptr, 0
tail call void @llvm.assume(i1 %maskcond)
%0 = load i32, i32* %a, align 4
ret i32 %0
%t0 = load i32, i32* %a, align 4
ret i32 %t0
}
declare void @llvm.assume(i1) #1
define i32 @simple(i32 %a) #1 {
; CHECK-LABEL: @simple(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 4
; CHECK-NEXT: tail call void @llvm.assume(i1 [[CMP]])
; CHECK-NEXT: ret i32 4
;
entry:
%cmp = icmp eq i32 %a, 4
tail call void @llvm.assume(i1 %cmp)
ret i32 %a
@ -68,72 +58,55 @@ entry:
define i32 @can1(i1 %a, i1 %b, i1 %c) {
; CHECK-LABEL: @can1(
; CHECK-NEXT: entry:
; CHECK-NEXT: call void @llvm.assume(i1 [[A:%.*]])
; CHECK-NEXT: call void @llvm.assume(i1 [[B:%.*]])
; CHECK-NEXT: call void @llvm.assume(i1 [[C:%.*]])
; CHECK-NEXT: ret i32 5
;
entry:
%and1 = and i1 %a, %b
%and = and i1 %and1, %c
tail call void @llvm.assume(i1 %and)
ret i32 5
}
define i32 @can2(i1 %a, i1 %b, i1 %c) {
; CHECK-LABEL: @can2(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[A:%.*]], true
; CHECK-NEXT: call void @llvm.assume(i1 [[TMP0]])
; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[B:%.*]], true
; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[A:%.*]], true
; CHECK-NEXT: call void @llvm.assume(i1 [[TMP1]])
; CHECK-NEXT: [[TMP2:%.*]] = xor i1 [[B:%.*]], true
; CHECK-NEXT: call void @llvm.assume(i1 [[TMP2]])
; CHECK-NEXT: ret i32 5
;
entry:
%v = or i1 %a, %b
%w = xor i1 %v, 1
tail call void @llvm.assume(i1 %w)
ret i32 5
}
define i32 @bar1(i32 %a) #0 {
; CHECK-LABEL: @bar1(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], 7
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 1
; CHECK-NEXT: tail call void @llvm.assume(i1 [[CMP]])
; CHECK-NEXT: ret i32 1
;
entry:
%and1 = and i32 %a, 3
%and = and i32 %a, 7
%cmp = icmp eq i32 %and, 1
tail call void @llvm.assume(i1 %cmp)
ret i32 %and1
}
define i32 @bar2(i32 %a) #0 {
; CHECK-LABEL: @bar2(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], 7
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 1
; CHECK-NEXT: tail call void @llvm.assume(i1 [[CMP]])
; CHECK-NEXT: ret i32 1
;
entry:
%and = and i32 %a, 7
%cmp = icmp eq i32 %and, 1
tail call void @llvm.assume(i1 %cmp)
%and1 = and i32 %a, 3
ret i32 %and1
}
@ -176,15 +149,11 @@ define i32 @bar4(i32 %a, i32 %b) {
;
entry:
%and1 = and i32 %b, 3
%and = and i32 %a, 7
%cmp = icmp eq i32 %and, 1
tail call void @llvm.assume(i1 %cmp)
%cmp2 = icmp eq i32 %a, %b
tail call void @llvm.assume(i1 %cmp2)
ret i32 %and1
}
@ -377,10 +346,10 @@ define i32 @assumption_conflicts_with_known_bits(i32 %a, i32 %b) {
define void @debug_interference(i8 %x) {
; CHECK-LABEL: @debug_interference(
; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i8 [[X:%.*]], 0
; CHECK-NEXT: tail call void @llvm.dbg.value(metadata i32 5, metadata !7, metadata !DIExpression()), !dbg !9
; CHECK-NEXT: tail call void @llvm.dbg.value(metadata i32 5, [[META7:metadata !.*]], metadata !DIExpression()), [[DBG9:!dbg !.*]]
; CHECK-NEXT: tail call void @llvm.assume(i1 false)
; CHECK-NEXT: tail call void @llvm.dbg.value(metadata i32 5, metadata !7, metadata !DIExpression()), !dbg !9
; CHECK-NEXT: tail call void @llvm.dbg.value(metadata i32 5, metadata !7, metadata !DIExpression()), !dbg !9
; CHECK-NEXT: tail call void @llvm.dbg.value(metadata i32 5, [[META7]], metadata !DIExpression()), [[DBG9]]
; CHECK-NEXT: tail call void @llvm.dbg.value(metadata i32 5, [[META7]], metadata !DIExpression()), [[DBG9]]
; CHECK-NEXT: tail call void @llvm.assume(i1 [[CMP2]])
; CHECK-NEXT: ret void
;
@ -532,7 +501,6 @@ define void @always_true_assumption() {
;
call void @llvm.assume(i1 true)
ret void
}
; The alloca guarantees that the low bits of %a are zero because of alignment.
@ -588,6 +556,47 @@ define void @PR36270(i32 %b) {
unreachable
}
; PR47416
define i32 @unreachable_assume(i32 %x, i32 %y) {
; CHECK-LABEL: @unreachable_assume(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP0:%.*]] = icmp sgt i32 [[X:%.*]], 1
; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[Y:%.*]], 1
; CHECK-NEXT: [[OR:%.*]] = or i1 [[CMP0]], [[CMP1]]
; CHECK-NEXT: tail call void @llvm.assume(i1 [[OR]])
; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[X]], 1
; CHECK-NEXT: br i1 [[CMP2]], label [[IF:%.*]], label [[EXIT:%.*]]
; CHECK: if:
; CHECK-NEXT: [[A:%.*]] = and i32 [[Y]], -2
; CHECK-NEXT: [[CMP3:%.*]] = icmp ne i32 [[A]], 104
; CHECK-NEXT: tail call void @llvm.assume(i1 [[CMP3]])
; CHECK-NEXT: br label [[EXIT]]
; CHECK: exit:
; CHECK-NEXT: [[CMP4:%.*]] = icmp eq i32 [[X]], 2
; CHECK-NEXT: tail call void @llvm.assume(i1 [[CMP4]])
; CHECK-NEXT: unreachable
;
entry:
%cmp0 = icmp sgt i32 %x, 1
%cmp1 = icmp eq i32 %y, 1
%or = or i1 %cmp0, %cmp1
tail call void @llvm.assume(i1 %or)
%cmp2 = icmp eq i32 %x, 1
br i1 %cmp2, label %if, label %exit
if:
%a = and i32 %y, -2
%cmp3 = icmp ne i32 %a, 104
tail call void @llvm.assume(i1 %cmp3)
br label %exit
exit:
%cmp4 = icmp eq i32 %x, 2
tail call void @llvm.assume(i1 %cmp4)
unreachable
}
declare void @llvm.dbg.value(metadata, metadata, metadata)
!llvm.dbg.cu = !{!0}