| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 
 | ; RUN: opt -lower-constant-intrinsics -S < %s | FileCheck %s
;; Ensure that an unfoldable is.constant gets lowered reasonably in
;; optimized codegen, in particular, that the "true" branch is
;; eliminated.
;; Also ensure that any unfoldable objectsize is resolved in order.
;; CHECK-NOT: tail call i32 @subfun_1()
;; CHECK:     tail call i32 @subfun_2()
;; CHECK-NOT: tail call i32 @subfun_1()
declare i1 @llvm.is.constant.i32(i32 %a) nounwind readnone
declare i1 @llvm.is.constant.i64(i64 %a) nounwind readnone
declare i1 @llvm.is.constant.i256(i256 %a) nounwind readnone
declare i1 @llvm.is.constant.v2i64(<2 x i64> %a) nounwind readnone
declare i1 @llvm.is.constant.f32(float %a) nounwind readnone
declare i1 @llvm.is.constant.sl_i32i32s({i32, i32} %a) nounwind readnone
declare i1 @llvm.is.constant.a2i64([2 x i64] %a) nounwind readnone
declare i1 @llvm.is.constant.p0i64(i64* %a) nounwind readnone
declare i64 @llvm.objectsize.i64.p0i8(i8*, i1, i1, i1) nounwind readnone
declare i32 @subfun_1()
declare i32 @subfun_2()
define i32 @test_branch(i32 %in) nounwind {
  %v = call i1 @llvm.is.constant.i32(i32 %in)
  br i1 %v, label %True, label %False
True:
  %call1 = tail call i32 @subfun_1()
  ret i32 %call1
False:
  %call2 = tail call i32 @subfun_2()
  ret i32 %call2
}
;; llvm.objectsize is another tricky case which gets folded to -1 very
;; late in the game. We'd like to ensure that llvm.is.constant of
;; llvm.objectsize is true.
define i1 @test_objectsize(i8* %obj) nounwind {
;; CHECK-LABEL:    test_objectsize
;; CHECK-NOT:      llvm.objectsize
;; CHECK-NOT:      llvm.is.constant
;; CHECK:          ret i1 true
  %os = call i64 @llvm.objectsize.i64.p0i8(i8* %obj, i1 false, i1 false, i1 false)
  %os1 = add i64 %os, 1
  %v = call i1 @llvm.is.constant.i64(i64 %os1)
  ret i1 %v
}
@test_phi_a = dso_local global i32 0, align 4
declare dso_local i32 @test_phi_b(...)
; Function Attrs: nounwind uwtable
define dso_local i32 @test_phi() {
entry:
  %0 = load i32, i32* @test_phi_a, align 4
  %1 = tail call i1 @llvm.is.constant.i32(i32 %0)
  br i1 %1, label %cond.end, label %cond.false
cond.false:                                       ; preds = %entry
  %call = tail call i32 bitcast (i32 (...)* @test_phi_b to i32 ()*)() #3
  %.pre = load i32, i32* @test_phi_a, align 4
  br label %cond.end
cond.end:                                         ; preds = %entry, %cond.false
  %2 = phi i32 [ %.pre, %cond.false ], [ %0, %entry ]
  %cond = phi i32 [ %call, %cond.false ], [ 1, %entry ]
  %cmp = icmp eq i32 %cond, %2
  br i1 %cmp, label %cond.true1, label %cond.end4
cond.true1:                                       ; preds = %cond.end
  %call2 = tail call i32 bitcast (i32 (...)* @test_phi_b to i32 ()*)() #3
  br label %cond.end4
cond.end4:                                        ; preds = %cond.end, %cond.true1
  ret i32 undef
}
define i1 @test_various_types(i256 %int, float %float, <2 x i64> %vec, {i32, i32} %struct, [2 x i64] %arr, i64* %ptr) #0 {
; CHECK-LABEL: @test_various_types(
; CHECK-NOT: llvm.is.constant
  %v1 = call i1 @llvm.is.constant.i256(i256 %int)
  %v2 = call i1 @llvm.is.constant.f32(float %float)
  %v3 = call i1 @llvm.is.constant.v2i64(<2 x i64> %vec)
  %v4 = call i1 @llvm.is.constant.sl_i32i32s({i32, i32} %struct)
  %v5 = call i1 @llvm.is.constant.a2i64([2 x i64] %arr)
  %v6 = call i1 @llvm.is.constant.p0i64(i64* %ptr)
  %c1 = call i1 @llvm.is.constant.i256(i256 -1)
  %c2 = call i1 @llvm.is.constant.f32(float 17.0)
  %c3 = call i1 @llvm.is.constant.v2i64(<2 x i64> <i64 -1, i64 44>)
  %c4 = call i1 @llvm.is.constant.sl_i32i32s({i32, i32} {i32 -1, i32 32})
  %c5 = call i1 @llvm.is.constant.a2i64([2 x i64] [i64 -1, i64 32])
  %c6 = call i1 @llvm.is.constant.p0i64(i64* inttoptr (i32 42 to i64*))
  %x1 = add i1 %v1, %c1
  %x2 = add i1 %v2, %c2
  %x3 = add i1 %v3, %c3
  %x4 = add i1 %v4, %c4
  %x5 = add i1 %v5, %c5
  %x6 = add i1 %v6, %c6
  %res2 = add i1 %x1, %x2
  %res3 = add i1 %res2, %x3
  %res4 = add i1 %res3, %x4
  %res5 = add i1 %res4, %x5
  %res6 = add i1 %res5, %x6
  ret i1 %res6
}
@real_mode_blob_end = external dso_local global [0 x i8], align 1
define i1 @global_array() {
; CHECK-LABEL: @global_array(
; CHECK-NEXT: ret i1 false
  %1 = call i1 @llvm.is.constant.i64(i64 ptrtoint ([0 x i8]* @real_mode_blob_end to i64))
  ret i1 %1
}
 |