blob: 4a3e3b63bb0fa4bb4192b054b03cdaedfe16e378 [file] [edit]
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -S --passes='simplifycfg<hoist-common-insts>' %s | FileCheck %s
declare void @llvm.pseudoprobe(i64, i64, i32, i64)
; Check that instructions past the pseudoprobe instrs are still hoisted into the predecessor.
define void @hoist_loads_past_pseudoprobe(i1 %c, ptr %d, ptr %m, ptr %b, i32 %v) {
; CHECK-LABEL: @hoist_loads_past_pseudoprobe(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP1:%.*]] = load i16, ptr [[M:%.*]], align 2
; CHECK-NEXT: [[CONV0:%.*]] = zext i16 [[TMP1]] to i32
; CHECK-NEXT: [[TMP3:%.*]] = load i16, ptr [[M1:%.*]], align 2
; CHECK-NEXT: [[CONV1:%.*]] = zext i16 [[TMP3]] to i32
; CHECK-NEXT: br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
; CHECK: if.then:
; CHECK-NEXT: call void @llvm.pseudoprobe(i64 1, i64 1, i32 0, i64 -1)
; CHECK-NEXT: [[ADD:%.*]] = add i32 [[CONV0]], [[V:%.*]]
; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[ADD]], [[CONV1]]
; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[MUL]], 16
; CHECK-NEXT: [[CONV12:%.*]] = trunc i32 [[SHR]] to i16
; CHECK-NEXT: br label [[IF_END:%.*]]
; CHECK: if.else:
; CHECK-NEXT: call void @llvm.pseudoprobe(i64 1, i64 2, i32 0, i64 -1)
; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[CONV0]], [[V]]
; CHECK-NEXT: [[MUL24:%.*]] = mul i32 [[SUB]], [[CONV1]]
; CHECK-NEXT: [[SHR25:%.*]] = lshr i32 [[MUL24]], 16
; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[SHR25]] to i16
; CHECK-NEXT: [[CONV27:%.*]] = sub i16 0, [[TMP2]]
; CHECK-NEXT: br label [[IF_END]]
; CHECK: if.end:
; CHECK-NEXT: [[STOREMERGE:%.*]] = phi i16 [ [[CONV27]], [[IF_ELSE]] ], [ [[CONV12]], [[IF_THEN]] ]
; CHECK-NEXT: store i16 [[STOREMERGE]], ptr [[D:%.*]], align 2
; CHECK-NEXT: ret void
;
entry:
br i1 %c, label %if.then, label %if.else
if.then:
call void @llvm.pseudoprobe(i64 1, i64 1, i32 0, i64 -1)
%0 = load i16, ptr %b, align 2
%conv0a = zext i16 %0 to i32
%add = add i32 %conv0a, %v
%1 = load i16, ptr %m, align 2
%conv1a = zext i16 %1 to i32
%mul = mul i32 %add, %conv1a
%shr = lshr i32 %mul, 16
%conv12 = trunc i32 %shr to i16
br label %if.end
if.else:
call void @llvm.pseudoprobe(i64 1, i64 2, i32 0, i64 -1)
%2 = load i16, ptr %b, align 2
%conv0b = zext i16 %2 to i32
%sub = sub i32 %conv0b, %v
%3 = load i16, ptr %m, align 2
%conv1b = zext i16 %3 to i32
%mul24 = mul i32 %sub, %conv1b
%shr25 = lshr i32 %mul24, 16
%4 = trunc i32 %shr25 to i16
%conv27 = sub i16 0, %4
br label %if.end
if.end:
%storemerge = phi i16 [ %conv27, %if.else ], [ %conv12, %if.then ]
store i16 %storemerge, ptr %d, align 2
ret void
}
; Stores past pseudo probes are also hoisted into the predecessor.
define void @hoist_stores_past_pseudoprobe(i1 %c, ptr %d, ptr %d2, i32 %v) {
; CHECK-LABEL: @hoist_stores_past_pseudoprobe(
; CHECK-NEXT: entry:
; CHECK-NEXT: store i32 [[V:%.*]], ptr [[D:%.*]], align 4
; CHECK-NEXT: br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
; CHECK: if.then:
; CHECK-NEXT: call void @llvm.pseudoprobe(i64 2, i64 1, i32 0, i64 -1)
; CHECK-NEXT: store i32 0, ptr [[D2:%.*]], align 4
; CHECK-NEXT: br label [[IF_END:%.*]]
; CHECK: if.else:
; CHECK-NEXT: call void @llvm.pseudoprobe(i64 2, i64 2, i32 0, i64 -1)
; CHECK-NEXT: store i32 1, ptr [[D2]], align 4
; CHECK-NEXT: br label [[IF_END]]
; CHECK: if.end:
; CHECK-NEXT: ret void
;
entry:
br i1 %c, label %if.then, label %if.else
if.then:
call void @llvm.pseudoprobe(i64 2, i64 1, i32 0, i64 -1)
store i32 %v, ptr %d, align 4
store i32 0, ptr %d2, align 4
br label %if.end
if.else:
call void @llvm.pseudoprobe(i64 2, i64 2, i32 0, i64 -1)
store i32 %v, ptr %d, align 4
store i32 1, ptr %d2, align 4
br label %if.end
if.end:
ret void
}
declare ptr @callee(ptr, i32, i32)
define ptr @dont_hoist_musttail_past_pseudoprobe(ptr %a, i32 %b, i32 %c) {
; CHECK-LABEL: @dont_hoist_musttail_past_pseudoprobe(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[C:%.*]], 0
; CHECK-NEXT: br i1 [[COND]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
; CHECK: if.then:
; CHECK-NEXT: call void @llvm.pseudoprobe(i64 3, i64 1, i32 0, i64 -1)
; CHECK-NEXT: [[CALL:%.*]] = musttail call ptr @callee(ptr [[A:%.*]], i32 [[B:%.*]], i32 [[C]])
; CHECK-NEXT: ret ptr [[CALL]]
; CHECK: if.else:
; CHECK-NEXT: call void @llvm.pseudoprobe(i64 3, i64 2, i32 0, i64 -1)
; CHECK-NEXT: [[CALL2:%.*]] = musttail call ptr @callee(ptr [[A]], i32 [[B]], i32 [[C]])
; CHECK-NEXT: ret ptr [[CALL2]]
;
entry:
%cond = icmp eq i32 %c, 0
br i1 %cond, label %if.then, label %if.else
if.then:
call void @llvm.pseudoprobe(i64 3, i64 1, i32 0, i64 -1)
%call = musttail call ptr @callee(ptr %a, i32 %b, i32 %c)
ret ptr %call
if.else:
call void @llvm.pseudoprobe(i64 3, i64 2, i32 0, i64 -1)
%call2 = musttail call ptr @callee(ptr %a, i32 %b, i32 %c)
ret ptr %call2
}