blob: c96961762194efe1f12881737b8d71f76b10159f [file]
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
; RUN: opt -S -passes=gvn < %s | FileCheck %s
define i64 @ptrtoaddr_same(ptr %p) {
; CHECK-LABEL: define i64 @ptrtoaddr_same(
; CHECK-SAME: ptr [[P:%.*]]) {
; CHECK-NEXT: [[J:%.*]] = ptrtoaddr ptr [[P]] to i64
; CHECK-NEXT: ret i64 0
;
%i = ptrtoaddr ptr %p to i64
%j = ptrtoaddr ptr %p to i64
%sub = sub i64 %i, %j
ret i64 %sub
}
; Note that unlike for ptrtoint, it's not possible for ptrtoaddr to differ
; in result type for the same input.
define i64 @ptrtoaddr_different(ptr %p, ptr %p2) {
; CHECK-LABEL: define i64 @ptrtoaddr_different(
; CHECK-SAME: ptr [[P:%.*]], ptr [[P2:%.*]]) {
; CHECK-NEXT: [[I:%.*]] = ptrtoaddr ptr [[P]] to i64
; CHECK-NEXT: [[J:%.*]] = ptrtoaddr ptr [[P2]] to i64
; CHECK-NEXT: [[SUB:%.*]] = sub i64 [[I]], [[J]]
; CHECK-NEXT: ret i64 [[SUB]]
;
%i = ptrtoaddr ptr %p to i64
%j = ptrtoaddr ptr %p2 to i64
%sub = sub i64 %i, %j
ret i64 %sub
}
define i64 @ptrtoaddr_reuses_dominating_ptrtoint(ptr %p) {
; CHECK-LABEL: define i64 @ptrtoaddr_reuses_dominating_ptrtoint(
; CHECK-SAME: ptr [[P:%.*]]) {
; CHECK-NEXT: [[I:%.*]] = ptrtoint ptr [[P]] to i64
; CHECK-NEXT: [[R:%.*]] = add i64 [[I]], [[I]]
; CHECK-NEXT: ret i64 [[R]]
;
%i = ptrtoint ptr %p to i64
%a = ptrtoaddr ptr %p to i64
%r = add i64 %i, %a
ret i64 %r
}
define i64 @ptrtoint_not_replaced_by_dominating_ptrtoaddr(ptr %p) {
; CHECK-LABEL: define i64 @ptrtoint_not_replaced_by_dominating_ptrtoaddr(
; CHECK-SAME: ptr [[P:%.*]]) {
; CHECK-NEXT: [[A:%.*]] = ptrtoaddr ptr [[P]] to i64
; CHECK-NEXT: [[I:%.*]] = ptrtoint ptr [[P]] to i64
; CHECK-NEXT: [[R:%.*]] = add i64 [[A]], [[I]]
; CHECK-NEXT: ret i64 [[R]]
;
%a = ptrtoaddr ptr %p to i64
%i = ptrtoint ptr %p to i64
%r = add i64 %a, %i
ret i64 %r
}
; A ptrtoaddr to a narrower type than the dominating ptrtoint is not a
; replacement candidate (different values).
define i64 @ptrtoaddr_wrong_type(ptr %p) {
; CHECK-LABEL: define i64 @ptrtoaddr_wrong_type(
; CHECK-SAME: ptr [[P:%.*]]) {
; CHECK-NEXT: [[I:%.*]] = ptrtoint ptr [[P]] to i32
; CHECK-NEXT: [[A:%.*]] = ptrtoaddr ptr [[P]] to i64
; CHECK-NEXT: [[Z:%.*]] = zext i32 [[I]] to i64
; CHECK-NEXT: [[R:%.*]] = add i64 [[Z]], [[A]]
; CHECK-NEXT: ret i64 [[R]]
;
%i = ptrtoint ptr %p to i32
%a = ptrtoaddr ptr %p to i64
%z = zext i32 %i to i64
%r = add i64 %z, %a
ret i64 %r
}
define i64 @ptrtoint_not_pred_from_ptrtoaddr(ptr %p, i1 %c) {
; CHECK-LABEL: define i64 @ptrtoint_not_pred_from_ptrtoaddr(
; CHECK-SAME: ptr [[P:%.*]], i1 [[C:%.*]]) {
; CHECK-NEXT: [[A:%.*]] = ptrtoaddr ptr [[P]] to i64
; CHECK-NEXT: br i1 [[C]], label %[[THEN:.*]], label %[[ELSE:.*]]
; CHECK: [[THEN]]:
; CHECK-NEXT: br label %[[MERGE:.*]]
; CHECK: [[ELSE]]:
; CHECK-NEXT: br label %[[MERGE]]
; CHECK: [[MERGE]]:
; CHECK-NEXT: [[I:%.*]] = ptrtoint ptr [[P]] to i64
; CHECK-NEXT: ret i64 [[I]]
;
%a = ptrtoaddr ptr %p to i64
br i1 %c, label %then, label %else
then:
br label %merge
else:
br label %merge
merge:
%i = ptrtoint ptr %p to i64
ret i64 %i
}
define i64 @no_transitive_merge_of_ptrtoint_and_ptrtoaddr(ptr %p) {
; CHECK-LABEL: define i64 @no_transitive_merge_of_ptrtoint_and_ptrtoaddr(
; CHECK-SAME: ptr [[P:%.*]]) {
; CHECK-NEXT: [[A:%.*]] = ptrtoaddr ptr [[P]] to i64
; CHECK-NEXT: [[ADDA:%.*]] = add i64 [[A]], 7
; CHECK-NEXT: [[I:%.*]] = ptrtoint ptr [[P]] to i64
; CHECK-NEXT: [[ADDI:%.*]] = add i64 [[I]], 7
; CHECK-NEXT: [[R:%.*]] = add i64 [[ADDA]], [[ADDI]]
; CHECK-NEXT: ret i64 [[R]]
;
%a = ptrtoaddr ptr %p to i64
%adda = add i64 %a, 7
%i = ptrtoint ptr %p to i64
%addi = add i64 %i, 7
%r = add i64 %adda, %addi
ret i64 %r
}