mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-15 04:30:12 +00:00
1c0c67a007
From a combination of @llvm.assume calls (and perhaps through other means, such as range metadata), it is possible that all bits of a return value might be known. Previously, InstCombine did not check for this (which is understandable given assumptions of constant propagation), but means that we'd miss simple cases where assumptions are involved. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@217346 91177308-0d34-0410-b5e6-96231b3b80d8
192 lines
3.9 KiB
LLVM
192 lines
3.9 KiB
LLVM
; 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"
|
|
|
|
; Function Attrs: nounwind uwtable
|
|
define i32 @foo1(i32* %a) #0 {
|
|
entry:
|
|
%0 = load i32* %a, align 4
|
|
|
|
; Check that the alignment has been upgraded and that the assume has not
|
|
; been removed:
|
|
; CHECK-LABEL: @foo1
|
|
; CHECK-DAG: load i32* %a, align 32
|
|
; CHECK-DAG: call void @llvm.assume
|
|
; CHECK: ret i32
|
|
|
|
%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
|
|
}
|
|
|
|
; Function Attrs: nounwind uwtable
|
|
define i32 @foo2(i32* %a) #0 {
|
|
entry:
|
|
; Same check as in @foo1, but make sure it works if the assume is first too.
|
|
; CHECK-LABEL: @foo2
|
|
; CHECK-DAG: load i32* %a, align 32
|
|
; CHECK-DAG: call void @llvm.assume
|
|
; CHECK: ret i32
|
|
|
|
%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* %a, align 4
|
|
ret i32 %0
|
|
}
|
|
|
|
; Function Attrs: nounwind
|
|
declare void @llvm.assume(i1) #1
|
|
|
|
define i32 @simple(i32 %a) #1 {
|
|
entry:
|
|
|
|
; CHECK-LABEL: @simple
|
|
; CHECK: call void @llvm.assume
|
|
; CHECK: ret i32 4
|
|
|
|
%cmp = icmp eq i32 %a, 4
|
|
tail call void @llvm.assume(i1 %cmp)
|
|
ret i32 %a
|
|
}
|
|
|
|
; Function Attrs: nounwind uwtable
|
|
define i32 @can1(i1 %a, i1 %b, i1 %c) {
|
|
entry:
|
|
%and1 = and i1 %a, %b
|
|
%and = and i1 %and1, %c
|
|
tail call void @llvm.assume(i1 %and)
|
|
|
|
; CHECK-LABEL: @can1
|
|
; CHECK: call void @llvm.assume(i1 %a)
|
|
; CHECK: call void @llvm.assume(i1 %b)
|
|
; CHECK: call void @llvm.assume(i1 %c)
|
|
; CHECK: ret i32
|
|
|
|
ret i32 5
|
|
}
|
|
|
|
; Function Attrs: nounwind uwtable
|
|
define i32 @can2(i1 %a, i1 %b, i1 %c) {
|
|
entry:
|
|
%v = or i1 %a, %b
|
|
%w = xor i1 %v, 1
|
|
tail call void @llvm.assume(i1 %w)
|
|
|
|
; CHECK-LABEL: @can2
|
|
; CHECK: %[[V1:[^ ]+]] = xor i1 %a, true
|
|
; CHECK: call void @llvm.assume(i1 %[[V1]])
|
|
; CHECK: %[[V2:[^ ]+]] = xor i1 %b, true
|
|
; CHECK: call void @llvm.assume(i1 %[[V2]])
|
|
; CHECK: ret i32
|
|
|
|
ret i32 5
|
|
}
|
|
|
|
define i32 @bar1(i32 %a) #0 {
|
|
entry:
|
|
%and1 = and i32 %a, 3
|
|
|
|
; CHECK-LABEL: @bar1
|
|
; CHECK: call void @llvm.assume
|
|
; CHECK: ret i32 1
|
|
|
|
%and = and i32 %a, 7
|
|
%cmp = icmp eq i32 %and, 1
|
|
tail call void @llvm.assume(i1 %cmp)
|
|
|
|
ret i32 %and1
|
|
}
|
|
|
|
; Function Attrs: nounwind uwtable
|
|
define i32 @bar2(i32 %a) #0 {
|
|
entry:
|
|
; CHECK-LABEL: @bar2
|
|
; CHECK: call void @llvm.assume
|
|
; CHECK: ret i32 1
|
|
|
|
%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
|
|
}
|
|
|
|
; Function Attrs: nounwind uwtable
|
|
define i32 @bar3(i32 %a, i1 %x, i1 %y) #0 {
|
|
entry:
|
|
%and1 = and i32 %a, 3
|
|
|
|
; Don't be fooled by other assumes around.
|
|
; CHECK-LABEL: @bar3
|
|
; CHECK: call void @llvm.assume
|
|
; CHECK: ret i32 1
|
|
|
|
tail call void @llvm.assume(i1 %x)
|
|
|
|
%and = and i32 %a, 7
|
|
%cmp = icmp eq i32 %and, 1
|
|
tail call void @llvm.assume(i1 %cmp)
|
|
|
|
tail call void @llvm.assume(i1 %y)
|
|
|
|
ret i32 %and1
|
|
}
|
|
|
|
; Function Attrs: nounwind uwtable
|
|
define i32 @bar4(i32 %a, i32 %b) {
|
|
entry:
|
|
%and1 = and i32 %b, 3
|
|
|
|
; CHECK-LABEL: @bar4
|
|
; CHECK: call void @llvm.assume
|
|
; CHECK: call void @llvm.assume
|
|
; CHECK: ret i32 1
|
|
|
|
%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
|
|
}
|
|
|
|
define i32 @icmp1(i32 %a) #0 {
|
|
entry:
|
|
%cmp = icmp sgt i32 %a, 5
|
|
tail call void @llvm.assume(i1 %cmp)
|
|
%conv = zext i1 %cmp to i32
|
|
ret i32 %conv
|
|
|
|
; CHECK-LABEL: @icmp1
|
|
; CHECK: call void @llvm.assume
|
|
; CHECK: ret i32 1
|
|
|
|
}
|
|
|
|
; Function Attrs: nounwind uwtable
|
|
define i32 @icmp2(i32 %a) #0 {
|
|
entry:
|
|
%cmp = icmp sgt i32 %a, 5
|
|
tail call void @llvm.assume(i1 %cmp)
|
|
%0 = zext i1 %cmp to i32
|
|
%lnot.ext = xor i32 %0, 1
|
|
ret i32 %lnot.ext
|
|
|
|
; CHECK-LABEL: @icmp2
|
|
; CHECK: call void @llvm.assume
|
|
; CHECK: ret i32 0
|
|
}
|
|
|
|
attributes #0 = { nounwind uwtable }
|
|
attributes #1 = { nounwind }
|
|
|