Files
clang-p2996/llvm/test/Transforms/InstCombine/phi-int2ptr-fold.ll
Krishna d99260641b [InstCombine] Fold phi ( inttoptr/ptrtoint x ) to phi (x)
The inttoptr/ptrtoint roundtrip optimization is not always correct.
We are working towards removing this optimization and adding support to specific cases where this optimization works.

In this patch, we focus on phi-node operands with inttoptr casts.
We know that ptrtoint( inttoptr( ptrtoint x) ) is same as ptrtoint (x).
So, we want to remove this roundtrip cast which goes through phi-node.

Reviewed By: aqjune

Differential Revision: https://reviews.llvm.org/D106289
2021-08-03 17:52:59 +05:30

176 lines
5.6 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -instcombine -S -disable-i2p-p2i-opt < %s | FileCheck %s
target datalayout = "e-p:64:64-p1:16:16-p2:32:32:32-p3:64:64:64"
target triple = "x86_64-unknown-linux-gnu"
; convert ptrtoint [ phi[ inttoptr (ptrtoint (x) ) ] ---> ptrtoint (phi[x])
define i64 @func(i32** %X, i32** %Y, i1 %cond) {
; CHECK-LABEL: @func(
; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
; CHECK: bb1:
; CHECK-NEXT: br label [[EXIT:%.*]]
; CHECK: bb2:
; CHECK-NEXT: br label [[EXIT]]
; CHECK: exit:
; CHECK-NEXT: [[PHI_IN_IN:%.*]] = phi i32** [ [[X:%.*]], [[BB1]] ], [ [[Y:%.*]], [[BB2]] ]
; CHECK-NEXT: [[PHI_IN:%.*]] = ptrtoint i32** [[PHI_IN_IN]] to i64
; CHECK-NEXT: ret i64 [[PHI_IN]]
;
br i1 %cond, label %bb1, label %bb2
bb1:
%X.i = ptrtoint i32** %X to i64
%X.p = inttoptr i64 %X.i to i32*
br label %exit
bb2:
%Y.i = ptrtoint i32** %Y to i64
%Y.p = inttoptr i64 %Y.i to i32*
br label %exit
exit:
%phi = phi i32* [%X.p, %bb1], [%Y.p, %bb2]
%X.p.i = ptrtoint i32* %phi to i64
ret i64 %X.p.i
}
define i64 @func_single_operand(i32** %X, i32** %Y, i1 %cond) {
; CHECK-LABEL: @func_single_operand(
; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB1:%.*]], label [[EXIT:%.*]]
; CHECK: bb1:
; CHECK-NEXT: br label [[EXIT]]
; CHECK: exit:
; CHECK-NEXT: [[PHI_IN:%.*]] = phi i32** [ [[X:%.*]], [[BB1]] ], [ [[Y:%.*]], [[TMP0:%.*]] ]
; CHECK-NEXT: [[X_P_I:%.*]] = ptrtoint i32** [[PHI_IN]] to i64
; CHECK-NEXT: ret i64 [[X_P_I]]
;
%Y.p = bitcast i32** %Y to i32*
br i1 %cond, label %bb1, label %exit
bb1:
%X.i = ptrtoint i32** %X to i64
%X.p = inttoptr i64 %X.i to i32*
br label %exit
exit:
%phi = phi i32* [%X.p, %bb1], [%Y.p, %0]
%X.p.i = ptrtoint i32* %phi to i64
ret i64 %X.p.i
}
define i64 @func_pointer_different_types(i16** %X, i32** %Y, i1 %cond) {
; CHECK-LABEL: @func_pointer_different_types(
; CHECK-NEXT: [[Y_P:%.*]] = bitcast i32** [[Y:%.*]] to i32*
; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB1:%.*]], label [[EXIT:%.*]]
; CHECK: bb1:
; CHECK-NEXT: [[TMP1:%.*]] = bitcast i16** [[X:%.*]] to i32*
; CHECK-NEXT: br label [[EXIT]]
; CHECK: exit:
; CHECK-NEXT: [[PHI:%.*]] = phi i32* [ [[TMP1]], [[BB1]] ], [ [[Y_P]], [[TMP0:%.*]] ]
; CHECK-NEXT: [[X_P_I:%.*]] = ptrtoint i32* [[PHI]] to i64
; CHECK-NEXT: ret i64 [[X_P_I]]
;
%Y.p = bitcast i32** %Y to i32*
br i1 %cond, label %bb1, label %exit
bb1:
%X.i = ptrtoint i16** %X to i64
%X.p = inttoptr i64 %X.i to i32*
br label %exit
exit:
%phi = phi i32* [%X.p, %bb1], [%Y.p, %0]
%X.p.i = ptrtoint i32* %phi to i64
ret i64 %X.p.i
}
; Negative test - Wrong Integer type
define i64 @func_integer_type_too_small(i32** %X, i32** %Y, i1 %cond) {
; CHECK-LABEL: @func_integer_type_too_small(
; CHECK-NEXT: [[Y_P:%.*]] = bitcast i32** [[Y:%.*]] to i32*
; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB1:%.*]], label [[EXIT:%.*]]
; CHECK: bb1:
; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint i32** [[X:%.*]] to i64
; CHECK-NEXT: [[TMP2:%.*]] = and i64 [[TMP1]], 4294967295
; CHECK-NEXT: [[X_P:%.*]] = inttoptr i64 [[TMP2]] to i32*
; CHECK-NEXT: br label [[EXIT]]
; CHECK: exit:
; CHECK-NEXT: [[PHI:%.*]] = phi i32* [ [[X_P]], [[BB1]] ], [ [[Y_P]], [[TMP0:%.*]] ]
; CHECK-NEXT: [[X_P_I:%.*]] = ptrtoint i32* [[PHI]] to i64
; CHECK-NEXT: ret i64 [[X_P_I]]
;
%Y.p = bitcast i32** %Y to i32*
br i1 %cond, label %bb1, label %exit
bb1:
%X.i = ptrtoint i32** %X to i32
%X.p = inttoptr i32 %X.i to i32*
br label %exit
exit:
%phi = phi i32* [%X.p, %bb1], [%Y.p, %0]
%X.p.i = ptrtoint i32* %phi to i64
ret i64 %X.p.i
}
; Negative test - phi not used in ptrtoint
define i32* @func_phi_not_use_in_ptr2int(i32** %X, i32** %Y, i1 %cond) {
; CHECK-LABEL: @func_phi_not_use_in_ptr2int(
; CHECK-NEXT: [[Y_P:%.*]] = bitcast i32** [[Y:%.*]] to i32*
; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB1:%.*]], label [[EXIT:%.*]]
; CHECK: bb1:
; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint i32** [[X:%.*]] to i64
; CHECK-NEXT: [[TMP2:%.*]] = and i64 [[TMP1]], 4294967295
; CHECK-NEXT: [[X_P:%.*]] = inttoptr i64 [[TMP2]] to i32*
; CHECK-NEXT: br label [[EXIT]]
; CHECK: exit:
; CHECK-NEXT: [[PHI:%.*]] = phi i32* [ [[X_P]], [[BB1]] ], [ [[Y_P]], [[TMP0:%.*]] ]
; CHECK-NEXT: ret i32* [[PHI]]
;
%Y.p = bitcast i32** %Y to i32*
br i1 %cond, label %bb1, label %exit
bb1:
%X.i = ptrtoint i32** %X to i32
%X.p = inttoptr i32 %X.i to i32*
br label %exit
exit:
%phi = phi i32* [%X.p, %bb1], [%Y.p, %0]
ret i32* %phi
}
; Negative test - Pointers in different address spaces
define i64 @func_ptr_different_addrspace(i16 addrspace(2)* %X, i32** %Y, i1 %cond) {
; CHECK-LABEL: @func_ptr_different_addrspace(
; CHECK-NEXT: [[Y_P:%.*]] = bitcast i32** [[Y:%.*]] to i32*
; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB1:%.*]], label [[EXIT:%.*]]
; CHECK: bb1:
; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint i16 addrspace(2)* [[X:%.*]] to i32
; CHECK-NEXT: [[X_I:%.*]] = zext i32 [[TMP1]] to i64
; CHECK-NEXT: [[X_P:%.*]] = inttoptr i64 [[X_I]] to i32*
; CHECK-NEXT: br label [[EXIT]]
; CHECK: exit:
; CHECK-NEXT: [[PHI:%.*]] = phi i32* [ [[X_P]], [[BB1]] ], [ [[Y_P]], [[TMP0:%.*]] ]
; CHECK-NEXT: [[X_P_I:%.*]] = ptrtoint i32* [[PHI]] to i64
; CHECK-NEXT: ret i64 [[X_P_I]]
;
%Y.p = bitcast i32** %Y to i32*
br i1 %cond, label %bb1, label %exit
bb1:
%X.i = ptrtoint i16 addrspace(2)* %X to i64
%X.p = inttoptr i64 %X.i to i32*
br label %exit
exit:
%phi = phi i32* [%X.p, %bb1], [%Y.p, %0]
%X.p.i = ptrtoint i32* %phi to i64
ret i64 %X.p.i
}