Files
clang-p2996/llvm/test/Transforms/InstCombine/binop-select.ll
Sanjay Patel 362c23500a Revert "[InstCombine] allow more folds for multi-use selects (2nd try)"
This reverts commit 6eae6b3722.

This version of the patch results in the same DFSAN bot failure as before,
so my guess about the SimplifyQuery context instruction was wrong.
I don't know what the real bug is.
2022-11-13 11:47:21 -05:00

324 lines
9.5 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -passes=instcombine -S | FileCheck %s
declare void @use(i32)
declare void @use_f32(float)
declare void @use_v2f16(<2 x half>)
declare void @use_v2i8(<2 x i8>)
define i32 @test1(i1 %c, i32 %x, i32 %y) {
; CHECK-LABEL: @test1(
; CHECK-NEXT: [[SUB:%.*]] = sub i32 0, [[X:%.*]]
; CHECK-NEXT: [[COND:%.*]] = select i1 [[C:%.*]], i32 [[SUB]], i32 [[Y:%.*]]
; CHECK-NEXT: [[ADD:%.*]] = add i32 [[COND]], [[X]]
; CHECK-NEXT: ret i32 [[ADD]]
;
%sub = sub i32 0, %x
%cond = select i1 %c, i32 %sub, i32 %y
%add = add i32 %cond, %x
ret i32 %add
}
define i32 @test2(i1 %c, i32 %x, i32 %y) {
; CHECK-LABEL: @test2(
; CHECK-NEXT: [[SUB:%.*]] = sub i32 0, [[X:%.*]]
; CHECK-NEXT: [[COND:%.*]] = select i1 [[C:%.*]], i32 [[SUB]], i32 [[X]]
; CHECK-NEXT: [[ADD:%.*]] = add i32 [[COND]], [[X]]
; CHECK-NEXT: ret i32 [[ADD]]
;
%sub = sub i32 0, %x
%cond = select i1 %c, i32 %sub, i32 %x
%add = add i32 %cond, %x
ret i32 %add
}
define i32 @test3(i1 %c, i32 %x, i32 %y) {
; CHECK-LABEL: @test3(
; CHECK-NEXT: [[SUB:%.*]] = sub i32 0, [[X:%.*]]
; CHECK-NEXT: [[COND:%.*]] = select i1 [[C:%.*]], i32 [[SUB]], i32 1
; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[COND]], [[X]]
; CHECK-NEXT: ret i32 [[MUL]]
;
%sub = sub i32 0, %x
%cond = select i1 %c, i32 %sub, i32 1
%mul = mul i32 %cond, %x
ret i32 %mul
}
define i32 @test4(i1 %c, i32 %x, i32 %y) {
; CHECK-LABEL: @test4(
; CHECK-NEXT: [[SUB:%.*]] = sub i32 0, [[X:%.*]]
; CHECK-NEXT: [[COND:%.*]] = select i1 [[C:%.*]], i32 [[SUB]], i32 1
; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[COND]], [[X]]
; CHECK-NEXT: ret i32 [[MUL]]
;
%sub = sub i32 0, %x
%cond = select i1 %c, i32 %sub, i32 1
%mul = mul i32 %cond, %x
ret i32 %mul
}
define i32 @test5(i1 %c, i32 %x, i32 %y) {
; CHECK-LABEL: @test5(
; CHECK-NEXT: [[COND:%.*]] = select i1 [[C:%.*]], i32 [[X:%.*]], i32 0
; CHECK-NEXT: [[ADD:%.*]] = add i32 [[COND]], [[X]]
; CHECK-NEXT: ret i32 [[ADD]]
;
%cond = select i1 %c, i32 %x, i32 0
%add = add i32 %cond, %x
ret i32 %add
}
define i32 @test6(i1 %c, i32 %x, i32 %y) {
; CHECK-LABEL: @test6(
; CHECK-NEXT: [[COND:%.*]] = select i1 [[C:%.*]], i32 7, i32 [[X:%.*]]
; CHECK-NEXT: [[AND:%.*]] = and i32 [[COND]], [[X]]
; CHECK-NEXT: ret i32 [[AND]]
;
%cond = select i1 %c, i32 7, i32 %x
%and = and i32 %cond, %x
ret i32 %and
}
define i32 @test7(i1 %c, i32 %x) {
; CHECK-LABEL: @test7(
; CHECK-NEXT: [[SUB:%.*]] = sub i32 0, [[X:%.*]]
; CHECK-NEXT: [[COND:%.*]] = select i1 [[C:%.*]], i32 [[X]], i32 [[SUB]]
; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[X]], [[COND]]
; CHECK-NEXT: ret i32 [[DIV]]
;
%sub = sub i32 0, %x
%cond = select i1 %c, i32 %x, i32 %sub
%div = sdiv i32 %x, %cond
ret i32 %div
}
define i32 @test8(i1 %c, i32 %x, i32 %y) {
; CHECK-LABEL: @test8(
; CHECK-NEXT: [[COND:%.*]] = select i1 [[C:%.*]], i32 7, i32 [[Y:%.*]]
; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 42, [[COND]]
; CHECK-NEXT: ret i32 [[DIV]]
;
%cond = select i1 %c, i32 7, i32 %y
%div = sdiv i32 42, %cond
ret i32 %div
}
define i32 @test9(i1 %c, i32 %x, i32 %y) {
; CHECK-LABEL: @test9(
; CHECK-NEXT: [[COND:%.*]] = select i1 [[C:%.*]], i32 1, i32 [[X:%.*]]
; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 0, [[COND]]
; CHECK-NEXT: ret i32 [[SUB]]
;
%cond = select i1 %c, i32 1, i32 %x
%sub = sub nsw i32 0, %cond
ret i32 %sub
}
define i32 @test10(i1 %c, i32 %x, i32 %y) {
; CHECK-LABEL: @test10(
; CHECK-NEXT: [[COND:%.*]] = select i1 [[C:%.*]], i32 7, i32 [[Y:%.*]]
; CHECK-NEXT: [[DIV:%.*]] = udiv i32 42, [[COND]]
; CHECK-NEXT: ret i32 [[DIV]]
;
%cond = select i1 %c, i32 7, i32 %y
%div = udiv i32 42, %cond
ret i32 %div
}
define i32 @test11(i1 %c, i32 %x, i32 %y) {
; CHECK-LABEL: @test11(
; CHECK-NEXT: [[COND:%.*]] = select i1 [[C:%.*]], i32 7, i32 [[Y:%.*]]
; CHECK-NEXT: [[DIV:%.*]] = srem i32 42, [[COND]]
; CHECK-NEXT: ret i32 [[DIV]]
;
%cond = select i1 %c, i32 7, i32 %y
%div = srem i32 42, %cond
ret i32 %div
}
define i32 @test12(i1 %c, i32 %x, i32 %y) {
; CHECK-LABEL: @test12(
; CHECK-NEXT: [[COND:%.*]] = select i1 [[C:%.*]], i32 7, i32 [[Y:%.*]]
; CHECK-NEXT: [[DIV:%.*]] = urem i32 42, [[COND]]
; CHECK-NEXT: ret i32 [[DIV]]
;
%cond = select i1 %c, i32 7, i32 %y
%div = urem i32 42, %cond
ret i32 %div
}
define i32 @extra_use(i1 %c, i32 %x, i32 %y) {
; CHECK-LABEL: @extra_use(
; CHECK-NEXT: [[COND:%.*]] = select i1 [[C:%.*]], i32 1, i32 [[X:%.*]]
; CHECK-NEXT: tail call void @use(i32 [[COND]])
; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 0, [[COND]]
; CHECK-NEXT: ret i32 [[SUB]]
;
%cond = select i1 %c, i32 1, i32 %x
tail call void @use(i32 %cond)
%sub = sub nsw i32 0, %cond
ret i32 %sub
}
define i32 @extra_use2(i1 %c, i32 %x) {
; CHECK-LABEL: @extra_use2(
; CHECK-NEXT: [[SUB:%.*]] = sub i32 0, [[X:%.*]]
; CHECK-NEXT: [[COND:%.*]] = select i1 [[C:%.*]], i32 [[X]], i32 [[SUB]]
; CHECK-NEXT: tail call void @use(i32 [[COND]])
; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[COND]], [[X]]
; CHECK-NEXT: ret i32 [[DIV]]
;
%sub = sub i32 0, %x
%cond = select i1 %c, i32 %x, i32 %sub
tail call void @use(i32 %cond)
%div = sdiv i32 %cond, %x
ret i32 %div
}
define i32 @and_sel_op0(i1 %b) {
; CHECK-LABEL: @and_sel_op0(
; CHECK-NEXT: [[S:%.*]] = zext i1 [[B:%.*]] to i32
; CHECK-NEXT: ret i32 [[S]]
;
%s = select i1 %b, i32 25, i32 0
%r = and i32 %s, 1
ret i32 %r
}
define i32 @and_sel_op0_use(i1 %b) {
; CHECK-LABEL: @and_sel_op0_use(
; CHECK-NEXT: [[S:%.*]] = select i1 [[B:%.*]], i32 25, i32 0
; CHECK-NEXT: call void @use(i32 [[S]])
; CHECK-NEXT: [[R:%.*]] = and i32 [[S]], 1
; CHECK-NEXT: ret i32 [[R]]
;
%s = select i1 %b, i32 25, i32 0
call void @use(i32 %s)
%r = and i32 %s, 1
ret i32 %r
}
define i32 @mul_sel_op0(i1 %b, i32 %x) {
; CHECK-LABEL: @mul_sel_op0(
; CHECK-NEXT: [[R:%.*]] = select i1 [[B:%.*]], i32 0, i32 42
; CHECK-NEXT: ret i32 [[R]]
;
%d = udiv exact i32 42, %x
%s = select i1 %b, i32 0, i32 %d
%r = mul i32 %s, %x
ret i32 %r
}
define i32 @mul_sel_op0_use(i1 %b, i32 %x) {
; CHECK-LABEL: @mul_sel_op0_use(
; CHECK-NEXT: [[D:%.*]] = udiv exact i32 42, [[X:%.*]]
; CHECK-NEXT: [[S:%.*]] = select i1 [[B:%.*]], i32 0, i32 [[D]]
; CHECK-NEXT: call void @use(i32 [[S]])
; CHECK-NEXT: [[R:%.*]] = mul i32 [[S]], [[X]]
; CHECK-NEXT: ret i32 [[R]]
;
%d = udiv exact i32 42, %x
%s = select i1 %b, i32 0, i32 %d
call void @use(i32 %s)
%r = mul i32 %s, %x
ret i32 %r
}
define i32 @sub_sel_op1(i1 %b) {
; CHECK-LABEL: @sub_sel_op1(
; CHECK-NEXT: [[NOT_B:%.*]] = xor i1 [[B:%.*]], true
; CHECK-NEXT: [[R:%.*]] = zext i1 [[NOT_B]] to i32
; CHECK-NEXT: ret i32 [[R]]
;
%s = select i1 %b, i32 42, i32 41
%r = sub nsw i32 42, %s
ret i32 %r
}
define i32 @sub_sel_op1_use(i1 %b) {
; CHECK-LABEL: @sub_sel_op1_use(
; CHECK-NEXT: [[S:%.*]] = select i1 [[B:%.*]], i32 42, i32 41
; CHECK-NEXT: call void @use(i32 [[S]])
; CHECK-NEXT: [[R:%.*]] = sub nsw i32 42, [[S]]
; CHECK-NEXT: ret i32 [[R]]
;
%s = select i1 %b, i32 42, i32 41
call void @use(i32 %s)
%r = sub nsw i32 42, %s
ret i32 %r
}
define float @fadd_sel_op0(i1 %b, float %x) {
; CHECK-LABEL: @fadd_sel_op0(
; CHECK-NEXT: [[R:%.*]] = select nnan i1 [[B:%.*]], float 0xFFF0000000000000, float 0x7FF0000000000000
; CHECK-NEXT: ret float [[R]]
;
%s = select i1 %b, float 0xFFF0000000000000, float 0x7FF0000000000000
%r = fadd nnan float %s, %x
ret float %r
}
define float @fadd_sel_op0_use(i1 %b, float %x) {
; CHECK-LABEL: @fadd_sel_op0_use(
; CHECK-NEXT: [[S:%.*]] = select i1 [[B:%.*]], float 0xFFF0000000000000, float 0x7FF0000000000000
; CHECK-NEXT: call void @use_f32(float [[S]])
; CHECK-NEXT: [[R:%.*]] = fadd nnan float [[S]], [[X:%.*]]
; CHECK-NEXT: ret float [[R]]
;
%s = select i1 %b, float 0xFFF0000000000000, float 0x7FF0000000000000
call void @use_f32(float %s)
%r = fadd nnan float %s, %x
ret float %r
}
define <2 x half> @fmul_sel_op1(i1 %b, <2 x half> %p) {
; CHECK-LABEL: @fmul_sel_op1(
; CHECK-NEXT: ret <2 x half> zeroinitializer
;
%x = fadd <2 x half> %p, <half 1.0, half 2.0> ; thwart complexity-based canonicalization
%s = select i1 %b, <2 x half> zeroinitializer, <2 x half> <half 0xHffff, half 0xHffff>
%r = fmul nnan nsz <2 x half> %x, %s
ret <2 x half> %r
}
define <2 x half> @fmul_sel_op1_use(i1 %b, <2 x half> %p) {
; CHECK-LABEL: @fmul_sel_op1_use(
; CHECK-NEXT: [[X:%.*]] = fadd <2 x half> [[P:%.*]], <half 0xH3C00, half 0xH4000>
; CHECK-NEXT: [[S:%.*]] = select i1 [[B:%.*]], <2 x half> zeroinitializer, <2 x half> <half 0xHFFFF, half 0xHFFFF>
; CHECK-NEXT: call void @use_v2f16(<2 x half> [[S]])
; CHECK-NEXT: [[R:%.*]] = fmul nnan nsz <2 x half> [[X]], [[S]]
; CHECK-NEXT: ret <2 x half> [[R]]
;
%x = fadd <2 x half> %p, <half 1.0, half 2.0> ; thwart complexity-based canonicalization
%s = select i1 %b, <2 x half> zeroinitializer, <2 x half> <half 0xHffff, half 0xHffff>
call void @use_v2f16(<2 x half> %s)
%r = fmul nnan nsz <2 x half> %x, %s
ret <2 x half> %r
}
define i32 @ashr_sel_op1(i1 %b) {
; CHECK-LABEL: @ashr_sel_op1(
; CHECK-NEXT: [[R:%.*]] = select i1 [[B:%.*]], i32 -1, i32 -2
; CHECK-NEXT: ret i32 [[R]]
;
%s = select i1 %b, i32 2, i32 0
%r = ashr i32 -2, %s
ret i32 %r
}
define i32 @ashr_sel_op1_use(i1 %b) {
; CHECK-LABEL: @ashr_sel_op1_use(
; CHECK-NEXT: [[S:%.*]] = select i1 [[B:%.*]], i32 2, i32 0
; CHECK-NEXT: call void @use(i32 [[S]])
; CHECK-NEXT: [[R:%.*]] = ashr i32 -2, [[S]]
; CHECK-NEXT: ret i32 [[R]]
;
%s = select i1 %b, i32 2, i32 0
call void @use(i32 %s)
%r = ashr i32 -2, %s
ret i32 %r
}