diff --git a/llvm/test/Transforms/InstCombine/assume.ll b/llvm/test/Transforms/InstCombine/assume.ll index 6f33e83ee336..f8a7bb01ff64 100644 --- a/llvm/test/Transforms/InstCombine/assume.ll +++ b/llvm/test/Transforms/InstCombine/assume.ll @@ -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}