1 2 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 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
|
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -passes=newgvn -S | FileCheck %s
define float @_Z1if(float %p) {
; CHECK-LABEL: @_Z1if(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[P_ADDR:%.*]] = alloca float, align 4
; CHECK-NEXT: store float [[P:%.*]], ptr [[P_ADDR]], align 4
; CHECK-NEXT: [[CMP:%.*]] = fcmp ueq float [[P]], 3.000000e+00
; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])
; CHECK-NEXT: ret float [[P]]
;
entry:
%p.addr = alloca float, align 4
store float %p, ptr %p.addr, align 4
%0 = load float, ptr %p.addr, align 4
%cmp = fcmp ueq float %0, 3.000000e+00 ; no nnan flag - can't propagate
call void @llvm.assume(i1 %cmp)
ret float %0
}
; This test checks if constant propagation works for multiple node edges
define i32 @_Z1ii(i32 %p) {
; CHECK-LABEL: @_Z1ii(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[P:%.*]], 42
; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])
; CHECK-NEXT: br i1 true, label [[BB2:%.*]], label [[BB2]]
; CHECK: bb2:
; CHECK-NEXT: br i1 true, label [[BB2]], label [[BB2]]
; CHECK: 0:
; CHECK-NEXT: store i8 poison, ptr null, align 1
; CHECK-NEXT: ret i32 [[P]]
;
entry:
%cmp = icmp eq i32 %p, 42
call void @llvm.assume(i1 %cmp)
br i1 %cmp, label %bb2, label %bb2
bb2:
call void @llvm.assume(i1 true)
br i1 %cmp, label %bb2, label %bb2
ret i32 %p
}
define i32 @_Z1ij(i32 %p) {
; CHECK-LABEL: @_Z1ij(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[P:%.*]], 42
; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])
; CHECK-NEXT: br i1 true, label [[BB2:%.*]], label [[BB2]]
; CHECK: bb2:
; CHECK-NEXT: call void @llvm.assume(i1 true)
; CHECK-NEXT: br i1 true, label [[TMP0:%.*]], label [[BB2]]
; CHECK: 0:
; CHECK-NEXT: ret i32 42
;
entry:
%cmp = icmp eq i32 %p, 42
call void @llvm.assume(i1 %cmp)
br i1 %cmp, label %bb2, label %bb2
bb2:
%cmp2 = icmp eq i32 %p, 42
call void @llvm.assume(i1 %cmp2)
br i1 %cmp, label %0, label %bb2
ret i32 %p
}
define i32 @_Z1ik(i32 %p) {
; CHECK-LABEL: @_Z1ik(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[P:%.*]], 42
; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])
; CHECK-NEXT: br i1 true, label [[BB2:%.*]], label [[BB3:%.*]]
; CHECK: bb2:
; CHECK-NEXT: call void @llvm.assume(i1 false)
; CHECK-NEXT: ret i32 15
; CHECK: bb3:
; CHECK-NEXT: store i8 poison, ptr null, align 1
; CHECK-NEXT: ret i32 17
;
entry:
%cmp = icmp eq i32 %p, 42
call void @llvm.assume(i1 %cmp)
br i1 %cmp, label %bb2, label %bb3
bb2:
%cmp3 = icmp eq i32 %p, 43
call void @llvm.assume(i1 %cmp3)
ret i32 15
bb3:
ret i32 17
}
; This test checks if GVN can do the constant propagation correctly
; when there are multiple uses of the same assume value in the
; basic block that has a loop back-edge pointing to itself.
define i32 @_Z1il(i32 %val, i1 %k) {
; CHECK-LABEL: @_Z1il(
; CHECK-NEXT: br label [[NEXT:%.*]]
; CHECK: next:
; CHECK-NEXT: tail call void @llvm.assume(i1 [[K:%.*]])
; CHECK-NEXT: tail call void @llvm.assume(i1 true)
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[VAL:%.*]], 50
; CHECK-NEXT: br i1 [[CMP]], label [[NEXT]], label [[MEH:%.*]]
; CHECK: meh:
; CHECK-NEXT: ret i32 0
;
br label %next
next:
tail call void @llvm.assume(i1 %k)
tail call void @llvm.assume(i1 %k)
%cmp = icmp eq i32 %val, 50
br i1 %cmp, label %next, label %meh
meh:
ret i32 0
}
; This test checks if GVN can prevent the constant propagation correctly
; in the successor blocks that are not dominated by the basic block
; with the assume instruction.
define i1 @_z1im(i32 %val, i1 %k, i1 %j) {
; CHECK-LABEL: @_z1im(
; CHECK-NEXT: br i1 [[J:%.*]], label [[NEXT:%.*]], label [[MEH:%.*]]
; CHECK: next:
; CHECK-NEXT: tail call void @llvm.assume(i1 [[K:%.*]])
; CHECK-NEXT: tail call void @llvm.assume(i1 true)
; CHECK-NEXT: br label [[MEH]]
; CHECK: meh:
; CHECK-NEXT: ret i1 [[K]]
;
br i1 %j, label %next, label %meh
next:
tail call void @llvm.assume(i1 %k)
tail call void @llvm.assume(i1 %k)
br label %meh
meh:
ret i1 %k
}
declare void @llvm.assume(i1)
|