forked from OSchip/llvm-project
140 lines
4.9 KiB
LLVM
140 lines
4.9 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
; RUN: opt -S -gvn -opaque-pointers < %s | FileCheck %s
|
|
|
|
declare void @use(ptr)
|
|
declare void @use.i32(i32)
|
|
|
|
define void @gep_cse(ptr %p) {
|
|
; CHECK-LABEL: @gep_cse(
|
|
; CHECK-NEXT: [[GEP1:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 1
|
|
; CHECK-NEXT: [[GEP3:%.*]] = getelementptr i64, ptr [[P]], i64 1
|
|
; CHECK-NEXT: call void @use(ptr [[GEP1]])
|
|
; CHECK-NEXT: call void @use(ptr [[GEP1]])
|
|
; CHECK-NEXT: call void @use(ptr [[GEP3]])
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
%gep1 = getelementptr i32, ptr %p, i64 1
|
|
%gep2 = getelementptr i32, ptr %p, i64 1
|
|
%gep3 = getelementptr i64, ptr %p, i64 1
|
|
call void @use(ptr %gep1)
|
|
call void @use(ptr %gep2)
|
|
call void @use(ptr %gep3)
|
|
ret void
|
|
}
|
|
|
|
define i32 @phi_trans(i1 %c, ptr %p1, ptr %p2) {
|
|
; CHECK-LABEL: @phi_trans(
|
|
; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
|
|
; CHECK: if:
|
|
; CHECK-NEXT: [[GEP1:%.*]] = getelementptr i32, ptr [[P1:%.*]], i64 1
|
|
; CHECK-NEXT: [[V1:%.*]] = load i32, ptr [[GEP1]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[V1]]) #[[ATTR0:[0-9]+]]
|
|
; CHECK-NEXT: br label [[JOIN:%.*]]
|
|
; CHECK: else:
|
|
; CHECK-NEXT: [[GEP2:%.*]] = getelementptr i32, ptr [[P2:%.*]], i64 1
|
|
; CHECK-NEXT: [[V2:%.*]] = load i32, ptr [[GEP2]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[V2]]) #[[ATTR0]]
|
|
; CHECK-NEXT: br label [[JOIN]]
|
|
; CHECK: join:
|
|
; CHECK-NEXT: [[V:%.*]] = phi i32 [ [[V1]], [[IF]] ], [ [[V2]], [[ELSE]] ]
|
|
; CHECK-NEXT: [[PHI:%.*]] = phi ptr [ [[P1]], [[IF]] ], [ [[P2]], [[ELSE]] ]
|
|
; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[PHI]], i64 1
|
|
; CHECK-NEXT: ret i32 [[V]]
|
|
;
|
|
br i1 %c, label %if, label %else
|
|
|
|
if:
|
|
%gep1 = getelementptr i32, ptr %p1, i64 1
|
|
%v1 = load i32, ptr %gep1
|
|
call void @use(i32 %v1) readnone
|
|
br label %join
|
|
|
|
else:
|
|
%gep2 = getelementptr i32, ptr %p2, i64 1
|
|
%v2 = load i32, ptr %gep2
|
|
call void @use(i32 %v2) readnone
|
|
br label %join
|
|
|
|
join:
|
|
%phi = phi ptr [ %p1, %if ], [ %p2, %else ]
|
|
%gep = getelementptr i32, ptr %phi, i64 1
|
|
%v = load i32, ptr %gep
|
|
ret i32 %v
|
|
}
|
|
|
|
define i32 @phi_trans_different_types(i1 %c, ptr %p1, ptr %p2) {
|
|
; CHECK-LABEL: @phi_trans_different_types(
|
|
; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
|
|
; CHECK: if:
|
|
; CHECK-NEXT: [[GEP1:%.*]] = getelementptr i32, ptr [[P1:%.*]], i64 1
|
|
; CHECK-NEXT: [[V1:%.*]] = load i32, ptr [[GEP1]], align 4
|
|
; CHECK-NEXT: call void @use.i32(i32 [[V1]]) #[[ATTR0]]
|
|
; CHECK-NEXT: br label [[JOIN:%.*]]
|
|
; CHECK: else:
|
|
; CHECK-NEXT: [[GEP2:%.*]] = getelementptr i64, ptr [[P2:%.*]], i64 1
|
|
; CHECK-NEXT: [[V2:%.*]] = load i32, ptr [[GEP2]], align 4
|
|
; CHECK-NEXT: call void @use.i32(i32 [[V2]]) #[[ATTR0]]
|
|
; CHECK-NEXT: [[GEP_PHI_TRANS_INSERT:%.*]] = getelementptr i32, ptr [[P2]], i64 1
|
|
; CHECK-NEXT: [[V_PRE:%.*]] = load i32, ptr [[GEP_PHI_TRANS_INSERT]], align 4
|
|
; CHECK-NEXT: br label [[JOIN]]
|
|
; CHECK: join:
|
|
; CHECK-NEXT: [[V:%.*]] = phi i32 [ [[V1]], [[IF]] ], [ [[V_PRE]], [[ELSE]] ]
|
|
; CHECK-NEXT: [[PHI:%.*]] = phi ptr [ [[P1]], [[IF]] ], [ [[P2]], [[ELSE]] ]
|
|
; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[PHI]], i64 1
|
|
; CHECK-NEXT: ret i32 [[V]]
|
|
;
|
|
br i1 %c, label %if, label %else
|
|
|
|
if:
|
|
%gep1 = getelementptr i32, ptr %p1, i64 1
|
|
%v1 = load i32, ptr %gep1
|
|
call void @use.i32(i32 %v1) readnone
|
|
br label %join
|
|
|
|
else:
|
|
%gep2 = getelementptr i64, ptr %p2, i64 1
|
|
%v2 = load i32, ptr %gep2
|
|
call void @use.i32(i32 %v2) readnone
|
|
br label %join
|
|
|
|
join:
|
|
%phi = phi ptr [ %p1, %if ], [ %p2, %else ]
|
|
%gep = getelementptr i32, ptr %phi, i64 1
|
|
%v = load i32, ptr %gep
|
|
ret i32 %v
|
|
}
|
|
|
|
define i32 @select_pre(ptr %px, ptr %py) {
|
|
; CHECK-LABEL: @select_pre(
|
|
; CHECK-NEXT: [[T2:%.*]] = load i32, ptr [[PY:%.*]], align 4
|
|
; CHECK-NEXT: [[T3:%.*]] = load i32, ptr [[PX:%.*]], align 4
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[T2]], [[T3]]
|
|
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[CMP]], i32 [[T3]], i32 [[T2]]
|
|
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], ptr [[PX]], ptr [[PY]]
|
|
; CHECK-NEXT: ret i32 [[TMP1]]
|
|
;
|
|
%t2 = load i32, ptr %py, align 4
|
|
%t3 = load i32, ptr %px, align 4
|
|
%cmp = icmp slt i32 %t2, %t3
|
|
%select = select i1 %cmp, ptr %px, ptr %py
|
|
%r = load i32, ptr %select, align 4
|
|
ret i32 %r
|
|
}
|
|
|
|
define i64 @select_pre_different_types(ptr %px, ptr %py) {
|
|
; CHECK-LABEL: @select_pre_different_types(
|
|
; CHECK-NEXT: [[T2:%.*]] = load i32, ptr [[PY:%.*]], align 4
|
|
; CHECK-NEXT: [[T3:%.*]] = load i32, ptr [[PX:%.*]], align 4
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[T2]], [[T3]]
|
|
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], ptr [[PX]], ptr [[PY]]
|
|
; CHECK-NEXT: [[R:%.*]] = load i64, ptr [[SELECT]], align 4
|
|
; CHECK-NEXT: ret i64 [[R]]
|
|
;
|
|
%t2 = load i32, ptr %py, align 4
|
|
%t3 = load i32, ptr %px, align 4
|
|
%cmp = icmp slt i32 %t2, %t3
|
|
%select = select i1 %cmp, ptr %px, ptr %py
|
|
%r = load i64, ptr %select, align 4
|
|
ret i64 %r
|
|
}
|