bolt/deps/llvm-18.1.8/llvm/test/Transforms/InstCombine/known-bits.ll
2025-02-14 19:21:04 +01:00

293 lines
7.3 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -S -passes=instcombine < %s | FileCheck %s
define void @test_shl(i1 %x) {
; CHECK-LABEL: @test_shl(
; CHECK-NEXT: call void @sink(i8 0)
; CHECK-NEXT: ret void
;
%y = zext i1 %x to i8
%z = shl i8 64, %y
%a = and i8 %z, 1
call void @sink(i8 %a)
ret void
}
define void @test_lshr(i1 %x) {
; CHECK-LABEL: @test_lshr(
; CHECK-NEXT: call void @sink(i8 0)
; CHECK-NEXT: ret void
;
%y = zext i1 %x to i8
%z = lshr i8 64, %y
%a = and i8 %z, 1
call void @sink(i8 %a)
ret void
}
define void @test_ashr(i1 %x) {
; CHECK-LABEL: @test_ashr(
; CHECK-NEXT: call void @sink(i8 0)
; CHECK-NEXT: ret void
;
%y = zext i1 %x to i8
%z = ashr i8 -16, %y
%a = and i8 %z, 3
call void @sink(i8 %a)
ret void
}
define void @test_udiv(i8 %x) {
; CHECK-LABEL: @test_udiv(
; CHECK-NEXT: call void @sink(i8 0)
; CHECK-NEXT: ret void
;
%y = udiv i8 10, %x
%z = and i8 %y, 64
call void @sink(i8 %z)
ret void
}
define i8 @test_cond(i8 %x) {
; CHECK-LABEL: @test_cond(
; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 3
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[AND]], 0
; CHECK-NEXT: br i1 [[CMP]], label [[IF:%.*]], label [[EXIT:%.*]]
; CHECK: if:
; CHECK-NEXT: ret i8 -4
; CHECK: exit:
; CHECK-NEXT: [[OR2:%.*]] = or i8 [[X]], -4
; CHECK-NEXT: ret i8 [[OR2]]
;
%and = and i8 %x, 3
%cmp = icmp eq i8 %and, 0
br i1 %cmp, label %if, label %exit
if:
%or1 = or i8 %x, -4
ret i8 %or1
exit:
%or2 = or i8 %x, -4
ret i8 %or2
}
define i8 @test_cond_inv(i8 %x) {
; CHECK-LABEL: @test_cond_inv(
; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 3
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[AND]], 0
; CHECK-NEXT: call void @use(i1 [[CMP]])
; CHECK-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[IF:%.*]]
; CHECK: if:
; CHECK-NEXT: ret i8 -4
; CHECK: exit:
; CHECK-NEXT: [[OR2:%.*]] = or i8 [[X]], -4
; CHECK-NEXT: ret i8 [[OR2]]
;
%and = and i8 %x, 3
%cmp = icmp ne i8 %and, 0
call void @use(i1 %cmp)
br i1 %cmp, label %exit, label %if
if:
%or1 = or i8 %x, -4
ret i8 %or1
exit:
%or2 = or i8 %x, -4
ret i8 %or2
}
define i8 @test_cond_and(i8 %x, i1 %c) {
; CHECK-LABEL: @test_cond_and(
; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 3
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[AND]], 0
; CHECK-NEXT: [[COND:%.*]] = and i1 [[CMP]], [[C:%.*]]
; CHECK-NEXT: br i1 [[COND]], label [[IF:%.*]], label [[EXIT:%.*]]
; CHECK: if:
; CHECK-NEXT: [[OR1:%.*]] = or i8 [[X]], -4
; CHECK-NEXT: ret i8 [[OR1]]
; CHECK: exit:
; CHECK-NEXT: [[OR2:%.*]] = or i8 [[X]], -4
; CHECK-NEXT: ret i8 [[OR2]]
;
%and = and i8 %x, 3
%cmp = icmp eq i8 %and, 0
%cond = and i1 %cmp, %c
br i1 %cond, label %if, label %exit
if:
%or1 = or i8 %x, -4
ret i8 %or1
exit:
%or2 = or i8 %x, -4
ret i8 %or2
}
define i8 @test_cond_and_commuted(i8 %x, i1 %c1, i1 %c2) {
; CHECK-LABEL: @test_cond_and_commuted(
; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 3
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[AND]], 0
; CHECK-NEXT: [[C3:%.*]] = and i1 [[C1:%.*]], [[C2:%.*]]
; CHECK-NEXT: [[COND:%.*]] = and i1 [[C3]], [[CMP]]
; CHECK-NEXT: br i1 [[COND]], label [[IF:%.*]], label [[EXIT:%.*]]
; CHECK: if:
; CHECK-NEXT: [[OR1:%.*]] = or i8 [[X]], -4
; CHECK-NEXT: ret i8 [[OR1]]
; CHECK: exit:
; CHECK-NEXT: [[OR2:%.*]] = or i8 [[X]], -4
; CHECK-NEXT: ret i8 [[OR2]]
;
%and = and i8 %x, 3
%cmp = icmp eq i8 %and, 0
%c3 = and i1 %c1, %c2
%cond = and i1 %c3, %cmp
br i1 %cond, label %if, label %exit
if:
%or1 = or i8 %x, -4
ret i8 %or1
exit:
%or2 = or i8 %x, -4
ret i8 %or2
}
define i8 @test_cond_logical_and(i8 %x, i1 %c) {
; CHECK-LABEL: @test_cond_logical_and(
; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 3
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[AND]], 0
; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i1 [[C:%.*]], i1 false
; CHECK-NEXT: br i1 [[COND]], label [[IF:%.*]], label [[EXIT:%.*]]
; CHECK: if:
; CHECK-NEXT: [[OR1:%.*]] = or i8 [[X]], -4
; CHECK-NEXT: ret i8 [[OR1]]
; CHECK: exit:
; CHECK-NEXT: [[OR2:%.*]] = or i8 [[X]], -4
; CHECK-NEXT: ret i8 [[OR2]]
;
%and = and i8 %x, 3
%cmp = icmp eq i8 %and, 0
%cond = select i1 %cmp, i1 %c, i1 false
br i1 %cond, label %if, label %exit
if:
%or1 = or i8 %x, -4
ret i8 %or1
exit:
%or2 = or i8 %x, -4
ret i8 %or2
}
define i8 @test_cond_or_invalid(i8 %x, i1 %c) {
; CHECK-LABEL: @test_cond_or_invalid(
; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 3
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[AND]], 0
; CHECK-NEXT: [[COND:%.*]] = or i1 [[CMP]], [[C:%.*]]
; CHECK-NEXT: br i1 [[COND]], label [[IF:%.*]], label [[EXIT:%.*]]
; CHECK: if:
; CHECK-NEXT: [[OR1:%.*]] = or i8 [[X]], -4
; CHECK-NEXT: ret i8 [[OR1]]
; CHECK: exit:
; CHECK-NEXT: [[OR2:%.*]] = or i8 [[X]], -4
; CHECK-NEXT: ret i8 [[OR2]]
;
%and = and i8 %x, 3
%cmp = icmp eq i8 %and, 0
%cond = or i1 %cmp, %c
br i1 %cond, label %if, label %exit
if:
%or1 = or i8 %x, -4
ret i8 %or1
exit:
%or2 = or i8 %x, -4
ret i8 %or2
}
define i8 @test_cond_inv_or(i8 %x, i1 %c) {
; CHECK-LABEL: @test_cond_inv_or(
; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 3
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[AND]], 0
; CHECK-NEXT: [[COND:%.*]] = or i1 [[CMP]], [[C:%.*]]
; CHECK-NEXT: br i1 [[COND]], label [[IF:%.*]], label [[EXIT:%.*]]
; CHECK: if:
; CHECK-NEXT: [[OR1:%.*]] = or i8 [[X]], -4
; CHECK-NEXT: ret i8 [[OR1]]
; CHECK: exit:
; CHECK-NEXT: [[OR2:%.*]] = or i8 [[X]], -4
; CHECK-NEXT: ret i8 [[OR2]]
;
%and = and i8 %x, 3
%cmp = icmp ne i8 %and, 0
%cond = or i1 %cmp, %c
br i1 %cond, label %if, label %exit
if:
%or1 = or i8 %x, -4
ret i8 %or1
exit:
%or2 = or i8 %x, -4
ret i8 %or2
}
define i8 @test_cond_inv_logical_or(i8 %x, i1 %c) {
; CHECK-LABEL: @test_cond_inv_logical_or(
; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 3
; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i8 [[AND]], 0
; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP_NOT]], i1 [[C:%.*]], i1 false
; CHECK-NEXT: br i1 [[COND]], label [[IF:%.*]], label [[EXIT:%.*]]
; CHECK: if:
; CHECK-NEXT: [[OR1:%.*]] = or i8 [[X]], -4
; CHECK-NEXT: ret i8 [[OR1]]
; CHECK: exit:
; CHECK-NEXT: [[OR2:%.*]] = or i8 [[X]], -4
; CHECK-NEXT: ret i8 [[OR2]]
;
%and = and i8 %x, 3
%cmp = icmp ne i8 %and, 0
%cond = select i1 %cmp, i1 false, i1 %c
br i1 %cond, label %if, label %exit
if:
%or1 = or i8 %x, -4
ret i8 %or1
exit:
%or2 = or i8 %x, -4
ret i8 %or2
}
define i8 @test_cond_inv_and_invalid(i8 %x, i1 %c) {
; CHECK-LABEL: @test_cond_inv_and_invalid(
; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 3
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[AND]], 0
; CHECK-NEXT: [[COND:%.*]] = and i1 [[CMP]], [[C:%.*]]
; CHECK-NEXT: br i1 [[COND]], label [[IF:%.*]], label [[EXIT:%.*]]
; CHECK: if:
; CHECK-NEXT: [[OR1:%.*]] = or i8 [[X]], -4
; CHECK-NEXT: ret i8 [[OR1]]
; CHECK: exit:
; CHECK-NEXT: [[OR2:%.*]] = or i8 [[X]], -4
; CHECK-NEXT: ret i8 [[OR2]]
;
%and = and i8 %x, 3
%cmp = icmp ne i8 %and, 0
%cond = and i1 %cmp, %c
br i1 %cond, label %if, label %exit
if:
%or1 = or i8 %x, -4
ret i8 %or1
exit:
%or2 = or i8 %x, -4
ret i8 %or2
}
declare void @use(i1)
declare void @sink(i8)