Files
clang-p2996/llvm/test/Transforms/ArgumentPromotion/metadata.ll
Nikita Popov e6241cbdcb [Mem2Reg] Only convert !nonnull to assume if !noundef present
After D141386 !nonnull violation returns poison rather than
resulting in immediate undefined behavior. However, converting
it into an assume would result in IUB. As such, we can only
perform this transform if !noundef is also present.
2023-01-20 16:38:26 +01:00

92 lines
3.7 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
; RUN: opt < %s -passes=argpromotion -S | FileCheck %s
declare void @use.i32(i32)
declare void @use.p32(ptr)
define internal void @callee(ptr %p1, ptr %p2, ptr %p3, ptr %p4, ptr %p5, ptr %p6, ptr %p7) {
; CHECK-LABEL: define {{[^@]+}}@callee
; CHECK-SAME: (i32 [[P1_0_VAL:%.*]], ptr [[P2_0_VAL:%.*]], ptr [[P3_0_VAL:%.*]], ptr [[P4_0_VAL:%.*]], ptr [[P5_0_VAL:%.*]], ptr [[P6_0_VAL:%.*]], ptr [[P7_0_VAL:%.*]]) {
; CHECK-NEXT: [[TMP1:%.*]] = icmp ne ptr [[P2_0_VAL]], null
; CHECK-NEXT: call void @llvm.assume(i1 [[TMP1]])
; CHECK-NEXT: call void @use.i32(i32 [[P1_0_VAL]])
; CHECK-NEXT: call void @use.p32(ptr [[P2_0_VAL]])
; CHECK-NEXT: call void @use.p32(ptr [[P3_0_VAL]])
; CHECK-NEXT: call void @use.p32(ptr [[P4_0_VAL]])
; CHECK-NEXT: call void @use.p32(ptr [[P5_0_VAL]])
; CHECK-NEXT: call void @use.p32(ptr [[P6_0_VAL]])
; CHECK-NEXT: call void @use.p32(ptr [[P7_0_VAL]])
; CHECK-NEXT: ret void
;
%v1 = load i32, ptr %p1, !range !0
%v2 = load ptr, ptr %p2, !nonnull !1, !noundef !1
%v3 = load ptr, ptr %p3, !dereferenceable !2
%v4 = load ptr, ptr %p4, !dereferenceable_or_null !2
%v5 = load ptr, ptr %p5, !align !3
%v6 = load ptr, ptr %p6, !noundef !1
%v7 = load ptr, ptr %p7, !nontemporal !4
call void @use.i32(i32 %v1)
call void @use.p32(ptr %v2)
call void @use.p32(ptr %v3)
call void @use.p32(ptr %v4)
call void @use.p32(ptr %v5)
call void @use.p32(ptr %v6)
call void @use.p32(ptr %v7)
ret void
}
define void @caller(ptr %p1, ptr %p2, ptr %p3, ptr %p4, ptr %p5, ptr %p6, ptr %p7) {
; CHECK-LABEL: define {{[^@]+}}@caller
; CHECK-SAME: (ptr [[P1:%.*]], ptr [[P2:%.*]], ptr [[P3:%.*]], ptr [[P4:%.*]], ptr [[P5:%.*]], ptr [[P6:%.*]], ptr [[P7:%.*]]) {
; CHECK-NEXT: [[P1_VAL:%.*]] = load i32, ptr [[P1]], align 4, !range [[RNG0:![0-9]+]]
; CHECK-NEXT: [[P2_VAL:%.*]] = load ptr, ptr [[P2]], align 8, !nonnull !1, !noundef !1
; CHECK-NEXT: [[P3_VAL:%.*]] = load ptr, ptr [[P3]], align 8, !dereferenceable !2
; CHECK-NEXT: [[P4_VAL:%.*]] = load ptr, ptr [[P4]], align 8, !dereferenceable_or_null !2
; CHECK-NEXT: [[P5_VAL:%.*]] = load ptr, ptr [[P5]], align 8, !align !3
; CHECK-NEXT: [[P6_VAL:%.*]] = load ptr, ptr [[P6]], align 8, !noundef !1
; CHECK-NEXT: [[P7_VAL:%.*]] = load ptr, ptr [[P7]], align 8, !nontemporal !4
; CHECK-NEXT: call void @callee(i32 [[P1_VAL]], ptr [[P2_VAL]], ptr [[P3_VAL]], ptr [[P4_VAL]], ptr [[P5_VAL]], ptr [[P6_VAL]], ptr [[P7_VAL]])
; CHECK-NEXT: ret void
;
call void @callee(ptr %p1, ptr %p2, ptr %p3, ptr %p4, ptr %p5, ptr %p6, ptr %p7)
ret void
}
define internal ptr @callee_conditional(i1 %c, ptr dereferenceable(8) align 8 %p) {
; CHECK-LABEL: define {{[^@]+}}@callee_conditional
; CHECK-SAME: (i1 [[C:%.*]], ptr [[P_0_VAL:%.*]]) {
; CHECK-NEXT: br i1 [[C]], label [[IF:%.*]], label [[ELSE:%.*]]
; CHECK: if:
; CHECK-NEXT: [[TMP1:%.*]] = icmp ne ptr [[P_0_VAL]], null
; CHECK-NEXT: call void @llvm.assume(i1 [[TMP1]])
; CHECK-NEXT: ret ptr [[P_0_VAL]]
; CHECK: else:
; CHECK-NEXT: ret ptr null
;
br i1 %c, label %if, label %else
if:
%v = load ptr, ptr %p, !nonnull !1, !noundef !1
ret ptr %v
else:
ret ptr null
}
define void @caller_conditional(i1 %c, ptr %p) {
; CHECK-LABEL: define {{[^@]+}}@caller_conditional
; CHECK-SAME: (i1 [[C:%.*]], ptr [[P:%.*]]) {
; CHECK-NEXT: [[P_VAL:%.*]] = load ptr, ptr [[P]], align 8
; CHECK-NEXT: [[TMP1:%.*]] = call ptr @callee_conditional(i1 [[C]], ptr [[P_VAL]])
; CHECK-NEXT: ret void
;
call ptr @callee_conditional(i1 %c, ptr %p)
ret void
}
!0 = !{i32 0, i32 4}
!1 = !{}
!2 = !{i64 8}
!3 = !{i64 4}
!4 = !{i32 1}