aboutsummaryrefslogtreecommitdiff
path: root/test/Transforms
diff options
context:
space:
mode:
Diffstat (limited to 'test/Transforms')
-rw-r--r--test/Transforms/CodeExtractor/PartialInlineCallRef.ll56
-rw-r--r--test/Transforms/CodeExtractor/PartialInlineOptRemark.ll73
-rw-r--r--test/Transforms/CodeExtractor/unreachable-block.ll38
-rw-r--r--test/Transforms/ConstantHoisting/X86/ehpad.ll11
-rw-r--r--test/Transforms/GVN/invariant.group.ll12
-rw-r--r--test/Transforms/InferAddressSpaces/AMDGPU/infer-getelementptr.ll48
-rw-r--r--test/Transforms/InstCombine/add-sitofp.ll124
-rw-r--r--test/Transforms/InstCombine/amdgcn-intrinsics.ll6
-rw-r--r--test/Transforms/InstCombine/and-or-icmps.ll4
-rw-r--r--test/Transforms/InstCombine/and-or-not.ll570
-rw-r--r--test/Transforms/InstCombine/and.ll28
-rw-r--r--test/Transforms/InstCombine/apint-shift.ll7
-rw-r--r--test/Transforms/InstCombine/debuginfo-dce.ll42
-rw-r--r--test/Transforms/InstCombine/fsub.ll44
-rw-r--r--test/Transforms/InstCombine/intrinsics.ll26
-rw-r--r--test/Transforms/InstCombine/memset-1.ll9
-rw-r--r--test/Transforms/InstCombine/minmax-fold.ll6
-rw-r--r--test/Transforms/InstCombine/or-to-xor.ll55
-rw-r--r--test/Transforms/InstCombine/or.ll53
-rw-r--r--test/Transforms/InstCombine/pr17827.ll4
-rw-r--r--test/Transforms/InstCombine/shift.ll30
-rw-r--r--test/Transforms/InstCombine/xor2.ll75
-rw-r--r--test/Transforms/InstSimplify/AndOrXor.ll115
-rw-r--r--test/Transforms/InstSimplify/icmp-ranges.ll336
-rw-r--r--test/Transforms/JumpThreading/fold-not-thread.ll135
-rw-r--r--test/Transforms/LoadStoreVectorizer/AMDGPU/gep-bitcast.ll83
-rw-r--r--test/Transforms/LoopIdiom/non-integral-pointers.ll48
-rw-r--r--test/Transforms/LoopUnroll/not-rotated.ll26
-rw-r--r--test/Transforms/LoopVectorize/X86/float-induction-x86.ll63
-rw-r--r--test/Transforms/LoopVectorize/induction.ll24
-rw-r--r--test/Transforms/LoopVectorize/phi-cost.ll86
-rw-r--r--test/Transforms/LowerSwitch/phi-in-dead-block.ll40
-rw-r--r--test/Transforms/Mem2Reg/debug-alloca-phi.ll48
-rw-r--r--test/Transforms/ObjCARC/clang-arc-use-barrier.ll45
-rw-r--r--test/Transforms/ObjCARC/intrinsic-use.ll11
-rw-r--r--test/Transforms/PGOProfile/memop_size_opt.ll21
-rw-r--r--test/Transforms/SimplifyCFG/merge-cond-stores.ll33
-rw-r--r--test/Transforms/StructurizeCFG/invert-compare.ll60
-rw-r--r--test/Transforms/StructurizeCFG/one-loop-multiple-backedges.ll12
-rw-r--r--test/Transforms/StructurizeCFG/post-order-traversal-bug.ll3
-rw-r--r--test/Transforms/Util/libcalls-fast-math-inf-loop.ll60
41 files changed, 2031 insertions, 539 deletions
diff --git a/test/Transforms/CodeExtractor/PartialInlineCallRef.ll b/test/Transforms/CodeExtractor/PartialInlineCallRef.ll
new file mode 100644
index 000000000000..4465a0fd4852
--- /dev/null
+++ b/test/Transforms/CodeExtractor/PartialInlineCallRef.ll
@@ -0,0 +1,56 @@
+; RUN: opt < %s -partial-inliner -S | FileCheck %s
+; RUN: opt < %s -passes=partial-inliner -S | FileCheck %s
+
+
+; Function Attrs: nounwind
+declare void @foo(...) local_unnamed_addr #0
+
+; Function Attrs: noinline
+define i32 @caller(i32 (i32)* nocapture %arg, i32 (i32)* nocapture %arg1, i32 %arg2) local_unnamed_addr #1 {
+bb:
+ %tmp = tail call i32 %arg(i32 %arg2) #0
+ %tmp3 = tail call i32 %arg1(i32 %arg2) #0
+ %tmp4 = add nsw i32 %tmp3, %tmp
+ ret i32 %tmp4
+}
+
+; Function Attrs: nounwind
+define i32 @bar(i32 %arg) #0 {
+bb:
+ %tmp = icmp slt i32 %arg, 0
+ br i1 %tmp, label %bb1, label %bb2
+
+bb1: ; preds = %bb
+ tail call void (...) @foo() #0
+ tail call void (...) @foo() #0
+ tail call void (...) @foo() #0
+ tail call void (...) @foo() #0
+ tail call void (...) @foo() #0
+ tail call void (...) @foo() #0
+ tail call void (...) @foo() #0
+ tail call void (...) @foo() #0
+ tail call void (...) @foo() #0
+ br label %bb2
+
+bb2: ; preds = %bb1, %bb
+ %tmp3 = phi i32 [ 0, %bb1 ], [ 1, %bb ]
+ ret i32 %tmp3
+}
+
+; Function Attrs: nounwind
+define i32 @dummy_caller(i32 %arg) local_unnamed_addr #0 {
+bb:
+; CHECK-LABEL: @dummy_caller
+; check that caller is not wrongly inlined by partial inliner
+; CHECK: call i32 @caller
+; CHECK-NOT: call .* @bar
+ %tmp = tail call i32 @caller(i32 (i32)* nonnull @bar, i32 (i32)* nonnull @bar, i32 %arg)
+ ret i32 %tmp
+}
+
+attributes #0 = { nounwind }
+attributes #1 = { noinline }
+
+!llvm.ident = !{!0}
+
+!0 = !{!"clang version 5.0.0 (trunk 300897) (llvm/trunk 300947)"}
diff --git a/test/Transforms/CodeExtractor/PartialInlineOptRemark.ll b/test/Transforms/CodeExtractor/PartialInlineOptRemark.ll
new file mode 100644
index 000000000000..3ba03843046c
--- /dev/null
+++ b/test/Transforms/CodeExtractor/PartialInlineOptRemark.ll
@@ -0,0 +1,73 @@
+; RUN: opt -S -partial-inliner -pass-remarks=partial-inlining -disable-output < %s 2>&1 | FileCheck %s
+; RUN: opt -S -passes=partial-inliner -pass-remarks=partial-inlining -disable-output < %s 2>&1 | FileCheck %s
+; RUN: opt -S -partial-inliner -pass-remarks=partial-inlining -disable-output -max-partial-inlining=1 < %s 2>&1 | FileCheck %s
+; RUN: opt -S -passes=partial-inliner -pass-remarks=partial-inlining -disable-output -max-partial-inlining=1 < %s 2>&1 | FileCheck %s
+
+; RUN: opt -S -partial-inliner -pass-remarks=partial-inlining -disable-partial-inlining < %s 2>&1 | FileCheck --check-prefix=LIMIT %s
+; RUN: opt -S -passes=partial-inliner -pass-remarks=partial-inlining --disable-partial-inlining < %s 2>&1 | FileCheck --check-prefix=LIMIT %s
+; RUN: opt -S -partial-inliner -pass-remarks=partial-inlining -max-partial-inlining=0 < %s 2>&1 | FileCheck --check-prefix=LIMIT %s
+; RUN: opt -S -passes=partial-inliner -pass-remarks=partial-inlining -max-partial-inlining=0 < %s 2>&1 | FileCheck --check-prefix=LIMIT %s
+
+define i32 @bar(i32 %arg) local_unnamed_addr #0 !dbg !5 {
+bb:
+ %tmp = icmp slt i32 %arg, 0, !dbg !7
+ br i1 %tmp, label %bb1, label %bb2, !dbg !8
+
+bb1: ; preds = %bb
+ tail call void (...) @foo() #0, !dbg !9
+ tail call void (...) @foo() #0, !dbg !10
+ tail call void (...) @foo() #0, !dbg !11
+ tail call void (...) @foo() #0, !dbg !12
+ tail call void (...) @foo() #0, !dbg !13
+ tail call void (...) @foo() #0, !dbg !14
+ tail call void (...) @foo() #0, !dbg !15
+ tail call void (...) @foo() #0, !dbg !16
+ tail call void (...) @foo() #0, !dbg !17
+ br label %bb2, !dbg !18
+
+bb2: ; preds = %bb1, %bb
+ %tmp3 = phi i32 [ 0, %bb1 ], [ 1, %bb ]
+ ret i32 %tmp3, !dbg !19
+}
+
+; Function Attrs: nounwind
+declare void @foo(...) local_unnamed_addr #0
+
+; Function Attrs: nounwind
+define i32 @dummy_caller(i32 %arg) local_unnamed_addr #0 !dbg !20 {
+bb:
+; CHECK:remark{{.*}}bar partially inlined into dummy_caller
+; LIMIT-NOT:remark{{.*}}bar partially inlined into dummy_caller
+ %tmp = tail call i32 @bar(i32 %arg), !dbg !21
+ ret i32 %tmp, !dbg !22
+}
+
+attributes #0 = { nounwind }
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!3}
+!llvm.ident = !{!4}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: NoDebug, enums: !2)
+!1 = !DIFile(filename: "t.c", directory: "/tmp")
+!2 = !{}
+!3 = !{i32 2, !"Debug Info Version", i32 3}
+!4 = !{!"clang "}
+!5 = distinct !DISubprogram(name: "bar", scope: !1, file: !1, line: 3, type: !6, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: true, unit: !0, variables: !2)
+!6 = !DISubroutineType(types: !2)
+!7 = !DILocation(line: 4, column: 14, scope: !5)
+!8 = !DILocation(line: 4, column: 6, scope: !5)
+!9 = !DILocation(line: 5, column: 5, scope: !5)
+!10 = !DILocation(line: 6, column: 5, scope: !5)
+!11 = !DILocation(line: 7, column: 5, scope: !5)
+!12 = !DILocation(line: 8, column: 5, scope: !5)
+!13 = !DILocation(line: 9, column: 5, scope: !5)
+!14 = !DILocation(line: 10, column: 5, scope: !5)
+!15 = !DILocation(line: 11, column: 5, scope: !5)
+!16 = !DILocation(line: 12, column: 5, scope: !5)
+!17 = !DILocation(line: 13, column: 5, scope: !5)
+!18 = !DILocation(line: 14, column: 5, scope: !5)
+!19 = !DILocation(line: 17, column: 1, scope: !5)
+!20 = distinct !DISubprogram(name: "dummy_caller", scope: !1, file: !1, line: 19, type: !6, isLocal: false, isDefinition: true, scopeLine: 19, flags: DIFlagPrototyped, isOptimized: true, unit: !0, variables: !2)
+!21 = !DILocation(line: 21, column: 11, scope: !20)
+!22 = !DILocation(line: 21, column: 4, scope: !20)
diff --git a/test/Transforms/CodeExtractor/unreachable-block.ll b/test/Transforms/CodeExtractor/unreachable-block.ll
new file mode 100644
index 000000000000..d20a35718e68
--- /dev/null
+++ b/test/Transforms/CodeExtractor/unreachable-block.ll
@@ -0,0 +1,38 @@
+; RUN: opt -S -partial-inliner %s | FileCheck %s
+
+; CHECK-LABEL: define void @dipsy(
+; CHECK-NEXT: call void @tinkywinky.1_ontrue()
+; CHECK-NEXT: call void @patatuccio()
+; CHECK-NEXT: ret void
+; CHECK-NEXT: }
+
+; CHECK-LABEL: define internal void @tinkywinky.1_ontrue() {
+; CHECK-NEXT: newFuncRoot:
+; CHECK-NEXT: br label %ontrue
+; CHECK: .exitStub:
+; CHECK-NEXT: ret void
+; CHECK: ontrue:
+; CHECK-NEXT: call void @patatino()
+; CHECK-NEXT: br label %onfalse
+; CHECK: onfalse:
+; CHECK-NEXT: br label %.exitStub
+; CHECK-NEXT: }
+
+declare void @patatino()
+declare void @patatuccio()
+
+define fastcc void @tinkywinky() {
+ br i1 true, label %ontrue, label %onfalse
+ontrue:
+ call void @patatino()
+ br label %onfalse
+onfalse:
+ call void @patatuccio()
+ ret void
+cantreachme:
+ ret void
+}
+define void @dipsy() {
+ call fastcc void @tinkywinky()
+ ret void
+}
diff --git a/test/Transforms/ConstantHoisting/X86/ehpad.ll b/test/Transforms/ConstantHoisting/X86/ehpad.ll
index 3178e87f7548..4f87572f3447 100644
--- a/test/Transforms/ConstantHoisting/X86/ehpad.ll
+++ b/test/Transforms/ConstantHoisting/X86/ehpad.ll
@@ -1,4 +1,5 @@
; RUN: opt -S -consthoist < %s | FileCheck %s
+; RUN: opt -S -consthoist -consthoist-with-block-frequency=true < %s | FileCheck --check-prefix=BFIHOIST %s
; FIXME: The catchpad doesn't even use the constant, so a better fix would be to
; insert the bitcast in the catchpad block.
@@ -11,6 +12,16 @@ target triple = "x86_64-pc-windows-msvc"
; CHECK-NEXT: bitcast i64 9209618997431186100 to i64
; CHECK-NEXT: br i1 %tobool
+; BFIHOIST-LABEL: define i32 @main
+; BFIHOIST: then:
+; BFIHOIST: %[[CONST1:.*]] = bitcast i64 9209618997431186100 to i64
+; BFIHOIST: %add = add i64 %call4, %[[CONST1]]
+; BFIHOIST: br label %endif
+; BFIHOIST: else:
+; BFIHOIST: %[[CONST2:.*]] = bitcast i64 9209618997431186100 to i64
+; BFIHOIST: %add6 = add i64 %call5, %[[CONST2]]
+; BFIHOIST: br label %endif
+
; Function Attrs: norecurse
define i32 @main(i32 %argc, i8** nocapture readnone %argv) local_unnamed_addr #0 personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
%call = tail call i64 @fn(i64 0)
diff --git a/test/Transforms/GVN/invariant.group.ll b/test/Transforms/GVN/invariant.group.ll
index 570519bec520..787a1035d9cb 100644
--- a/test/Transforms/GVN/invariant.group.ll
+++ b/test/Transforms/GVN/invariant.group.ll
@@ -237,15 +237,16 @@ entry:
ret i8 %a
}
-; CHECK-LABEL: define i8 @unoptimizable4() {
-define i8 @unoptimizable4() {
+; CHECK-LABEL: define i8 @optimizable4() {
+define i8 @optimizable4() {
entry:
%ptr = alloca i8
store i8 42, i8* %ptr, !invariant.group !0
%ptr2 = call i8* @llvm.invariant.group.barrier(i8* %ptr)
+; CHECK-NOT: load
%a = load i8, i8* %ptr2, !invariant.group !0
-; CHECK: ret i8 %a
+; CHECK: ret i8 42
ret i8 %a
}
@@ -314,8 +315,9 @@ entry:
store i8 %unknownValue, i8* %ptr, !invariant.group !0
%newPtr2 = call i8* @llvm.invariant.group.barrier(i8* %ptr)
- %d = load i8, i8* %newPtr2, !invariant.group !0 ; Can't step through invariant.group.barrier to get value of %ptr
-; CHECK: ret i8 %d
+; CHECK-NOT: load
+ %d = load i8, i8* %newPtr2, !invariant.group !0
+; CHECK: ret i8 %unknownValue
ret i8 %d
}
diff --git a/test/Transforms/InferAddressSpaces/AMDGPU/infer-getelementptr.ll b/test/Transforms/InferAddressSpaces/AMDGPU/infer-getelementptr.ll
new file mode 100644
index 000000000000..6b94a74da35c
--- /dev/null
+++ b/test/Transforms/InferAddressSpaces/AMDGPU/infer-getelementptr.ll
@@ -0,0 +1,48 @@
+; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -infer-address-spaces %s | FileCheck %s
+
+; Test that pure GetElementPtr instructions not directly connected to
+; a memory operation are inferred.
+
+@lds = internal unnamed_addr addrspace(3) global [648 x double] undef, align 8
+
+; CHECK-LABEL: @constexpr_gep_addrspacecast(
+; CHECK: %gep0 = getelementptr inbounds double, double addrspace(4)* addrspacecast (double addrspace(3)* getelementptr inbounds ([648 x double], [648 x double] addrspace(3)* @lds, i64 0, i64 384) to double addrspace(4)*), i64 %idx0
+; CHECK-NEXT: %asc = addrspacecast double addrspace(4)* %gep0 to double addrspace(3)*
+; CHECK-NEXT: store double 1.000000e+00, double addrspace(3)* %asc
+define void @constexpr_gep_addrspacecast(i64 %idx0, i64 %idx1) {
+ %gep0 = getelementptr inbounds double, double addrspace(4)* getelementptr ([648 x double], [648 x double] addrspace(4)* addrspacecast ([648 x double] addrspace(3)* @lds to [648 x double] addrspace(4)*), i64 0, i64 384), i64 %idx0
+ %asc = addrspacecast double addrspace(4)* %gep0 to double addrspace(3)*
+ store double 1.0, double addrspace(3)* %asc, align 8
+ ret void
+}
+
+; CHECK-LABEL: @constexpr_gep_gep_addrspacecast(
+; CHECK: %gep0 = getelementptr inbounds double, double addrspace(3)* getelementptr inbounds ([648 x double], [648 x double] addrspace(3)* @lds, i64 0, i64 384), i64 %idx0
+; CHECK-NEXT: %1 = addrspacecast double addrspace(3)* %gep0 to double addrspace(4)*
+; CHECK-NEXT: %gep1 = getelementptr inbounds double, double addrspace(4)* %1, i64 %idx1
+; CHECK-NEXT: %asc = addrspacecast double addrspace(4)* %gep1 to double addrspace(3)*
+; CHECK-NEXT: store double 1.000000e+00, double addrspace(3)* %asc, align 8
+define void @constexpr_gep_gep_addrspacecast(i64 %idx0, i64 %idx1) {
+ %gep0 = getelementptr inbounds double, double addrspace(4)* getelementptr ([648 x double], [648 x double] addrspace(4)* addrspacecast ([648 x double] addrspace(3)* @lds to [648 x double] addrspace(4)*), i64 0, i64 384), i64 %idx0
+ %gep1 = getelementptr inbounds double, double addrspace(4)* %gep0, i64 %idx1
+ %asc = addrspacecast double addrspace(4)* %gep1 to double addrspace(3)*
+ store double 1.0, double addrspace(3)* %asc, align 8
+ ret void
+}
+
+; Don't crash
+; CHECK-LABEL: @vector_gep(
+; CHECK: %cast = addrspacecast <4 x [1024 x i32] addrspace(3)*> %array to <4 x [1024 x i32] addrspace(4)*>
+define amdgpu_kernel void @vector_gep(<4 x [1024 x i32] addrspace(3)*> %array) nounwind {
+ %cast = addrspacecast <4 x [1024 x i32] addrspace(3)*> %array to <4 x [1024 x i32] addrspace(4)*>
+ %p = getelementptr [1024 x i32], <4 x [1024 x i32] addrspace(4)*> %cast, <4 x i16> zeroinitializer, <4 x i16> <i16 16, i16 16, i16 16, i16 16>
+ %p0 = extractelement <4 x i32 addrspace(4)*> %p, i32 0
+ %p1 = extractelement <4 x i32 addrspace(4)*> %p, i32 1
+ %p2 = extractelement <4 x i32 addrspace(4)*> %p, i32 2
+ %p3 = extractelement <4 x i32 addrspace(4)*> %p, i32 3
+ store i32 99, i32 addrspace(4)* %p0
+ store i32 99, i32 addrspace(4)* %p1
+ store i32 99, i32 addrspace(4)* %p2
+ store i32 99, i32 addrspace(4)* %p3
+ ret void
+}
diff --git a/test/Transforms/InstCombine/add-sitofp.ll b/test/Transforms/InstCombine/add-sitofp.ll
index 2abfa436f6d3..105c9efa0893 100644
--- a/test/Transforms/InstCombine/add-sitofp.ll
+++ b/test/Transforms/InstCombine/add-sitofp.ll
@@ -15,3 +15,127 @@ define double @x(i32 %a, i32 %b) {
%p = fadd double %o, 1.0
ret double %p
}
+
+define double @test(i32 %a) {
+; CHECK-LABEL: @test(
+; CHECK-NEXT: [[A_AND:%.*]] = and i32 [[A:%.*]], 1073741823
+; CHECK-NEXT: [[ADDCONV:%.*]] = add nuw nsw i32 [[A_AND]], 1
+; CHECK-NEXT: [[RES:%.*]] = sitofp i32 [[ADDCONV]] to double
+; CHECK-NEXT: ret double [[RES]]
+;
+ ; Drop two highest bits to guarantee that %a + 1 doesn't overflow
+ %a_and = and i32 %a, 1073741823
+ %a_and_fp = sitofp i32 %a_and to double
+ %res = fadd double %a_and_fp, 1.0
+ ret double %res
+}
+
+define float @test_neg(i32 %a) {
+; CHECK-LABEL: @test_neg(
+; CHECK-NEXT: [[A_AND:%.*]] = and i32 [[A:%.*]], 1073741823
+; CHECK-NEXT: [[A_AND_FP:%.*]] = sitofp i32 [[A_AND]] to float
+; CHECK-NEXT: [[RES:%.*]] = fadd float [[A_AND_FP]], 1.000000e+00
+; CHECK-NEXT: ret float [[RES]]
+;
+ ; Drop two highest bits to guarantee that %a + 1 doesn't overflow
+ %a_and = and i32 %a, 1073741823
+ %a_and_fp = sitofp i32 %a_and to float
+ %res = fadd float %a_and_fp, 1.0
+ ret float %res
+}
+
+define double @test_2(i32 %a, i32 %b) {
+; CHECK-LABEL: @test_2(
+; CHECK-NEXT: [[A_AND:%.*]] = and i32 [[A:%.*]], 1073741823
+; CHECK-NEXT: [[B_AND:%.*]] = and i32 [[B:%.*]], 1073741823
+; CHECK-NEXT: [[ADDCONV:%.*]] = add nuw nsw i32 [[A_AND]], [[B_AND]]
+; CHECK-NEXT: [[RES:%.*]] = sitofp i32 [[ADDCONV]] to double
+; CHECK-NEXT: ret double [[RES]]
+;
+ ; Drop two highest bits to guarantee that %a + %b doesn't overflow
+ %a_and = and i32 %a, 1073741823
+ %b_and = and i32 %b, 1073741823
+
+ %a_and_fp = sitofp i32 %a_and to double
+ %b_and_fp = sitofp i32 %b_and to double
+
+ %res = fadd double %a_and_fp, %b_and_fp
+ ret double %res
+}
+
+define float @test_2_neg(i32 %a, i32 %b) {
+; CHECK-LABEL: @test_2_neg(
+; CHECK-NEXT: [[A_AND:%.*]] = and i32 [[A:%.*]], 1073741823
+; CHECK-NEXT: [[B_AND:%.*]] = and i32 [[B:%.*]], 1073741823
+; CHECK-NEXT: [[A_AND_FP:%.*]] = sitofp i32 [[A_AND]] to float
+; CHECK-NEXT: [[B_AND_FP:%.*]] = sitofp i32 [[B_AND]] to float
+; CHECK-NEXT: [[RES:%.*]] = fadd float [[A_AND_FP]], [[B_AND_FP]]
+; CHECK-NEXT: ret float [[RES]]
+;
+ ; Drop two highest bits to guarantee that %a + %b doesn't overflow
+ %a_and = and i32 %a, 1073741823
+ %b_and = and i32 %b, 1073741823
+
+ %a_and_fp = sitofp i32 %a_and to float
+ %b_and_fp = sitofp i32 %b_and to float
+
+ %res = fadd float %a_and_fp, %b_and_fp
+ ret float %res
+}
+
+; This test demonstrates overly conservative legality check. The float addition
+; can be replaced with the integer addition because the result of the operation
+; can be represented in float, but we don't do that now.
+define float @test_3(i32 %a, i32 %b) {
+; CHECK-LABEL: @test_3(
+; CHECK-NEXT: [[M:%.*]] = lshr i32 [[A:%.*]], 24
+; CHECK-NEXT: [[N:%.*]] = and i32 [[M]], [[B:%.*]]
+; CHECK-NEXT: [[O:%.*]] = sitofp i32 [[N]] to float
+; CHECK-NEXT: [[P:%.*]] = fadd float [[O]], 1.000000e+00
+; CHECK-NEXT: ret float [[P]]
+;
+ %m = lshr i32 %a, 24
+ %n = and i32 %m, %b
+ %o = sitofp i32 %n to float
+ %p = fadd float %o, 1.0
+ ret float %p
+}
+
+define <4 x double> @test_4(<4 x i32> %a, <4 x i32> %b) {
+; CHECK-LABEL: @test_4(
+; CHECK-NEXT: [[A_AND:%.*]] = and <4 x i32> [[A:%.*]], <i32 1073741823, i32 1073741823, i32 1073741823, i32 1073741823>
+; CHECK-NEXT: [[B_AND:%.*]] = and <4 x i32> [[B:%.*]], <i32 1073741823, i32 1073741823, i32 1073741823, i32 1073741823>
+; CHECK-NEXT: [[ADDCONV:%.*]] = add nuw nsw <4 x i32> [[A_AND]], [[B_AND]]
+; CHECK-NEXT: [[RES:%.*]] = sitofp <4 x i32> [[ADDCONV]] to <4 x double>
+; CHECK-NEXT: ret <4 x double> [[RES]]
+;
+ ; Drop two highest bits to guarantee that %a + %b doesn't overflow
+ %a_and = and <4 x i32> %a, <i32 1073741823, i32 1073741823, i32 1073741823, i32 1073741823>
+ %b_and = and <4 x i32> %b, <i32 1073741823, i32 1073741823, i32 1073741823, i32 1073741823>
+
+ %a_and_fp = sitofp <4 x i32> %a_and to <4 x double>
+ %b_and_fp = sitofp <4 x i32> %b_and to <4 x double>
+
+ %res = fadd <4 x double> %a_and_fp, %b_and_fp
+ ret <4 x double> %res
+}
+
+define <4 x float> @test_4_neg(<4 x i32> %a, <4 x i32> %b) {
+; CHECK-LABEL: @test_4_neg(
+; CHECK-NEXT: [[A_AND:%.*]] = and <4 x i32> [[A:%.*]], <i32 1073741823, i32 1073741823, i32 1073741823, i32 1073741823>
+; CHECK-NEXT: [[B_AND:%.*]] = and <4 x i32> [[B:%.*]], <i32 1073741823, i32 1073741823, i32 1073741823, i32 1073741823>
+; CHECK-NEXT: [[A_AND_FP:%.*]] = sitofp <4 x i32> [[A_AND]] to <4 x float>
+; CHECK-NEXT: [[B_AND_FP:%.*]] = sitofp <4 x i32> [[B_AND]] to <4 x float>
+; CHECK-NEXT: [[RES:%.*]] = fadd <4 x float> [[A_AND_FP]], [[B_AND_FP]]
+; CHECK-NEXT: ret <4 x float> [[RES]]
+;
+ ; Drop two highest bits to guarantee that %a + %b doesn't overflow
+ %a_and = and <4 x i32> %a, <i32 1073741823, i32 1073741823, i32 1073741823, i32 1073741823>
+ %b_and = and <4 x i32> %b, <i32 1073741823, i32 1073741823, i32 1073741823, i32 1073741823>
+
+ %a_and_fp = sitofp <4 x i32> %a_and to <4 x float>
+ %b_and_fp = sitofp <4 x i32> %b_and to <4 x float>
+
+ %res = fadd <4 x float> %a_and_fp, %b_and_fp
+ ret <4 x float> %res
+}
diff --git a/test/Transforms/InstCombine/amdgcn-intrinsics.ll b/test/Transforms/InstCombine/amdgcn-intrinsics.ll
index deae5502bcdb..357085fd31fe 100644
--- a/test/Transforms/InstCombine/amdgcn-intrinsics.ll
+++ b/test/Transforms/InstCombine/amdgcn-intrinsics.ll
@@ -1259,7 +1259,7 @@ define i64 @icmp_constant_inputs_false() {
}
; CHECK-LABEL: @icmp_constant_inputs_true(
-; CHECK: ret i64 -1
+; CHECK: %result = call i64 @llvm.read_register.i64(metadata !0) #4
define i64 @icmp_constant_inputs_true() {
%result = call i64 @llvm.amdgcn.icmp.i32(i32 9, i32 8, i32 34)
ret i64 %result
@@ -1524,7 +1524,7 @@ define i64 @fcmp_constant_inputs_false() {
}
; CHECK-LABEL: @fcmp_constant_inputs_true(
-; CHECK: ret i64 -1
+; CHECK: %result = call i64 @llvm.read_register.i64(metadata !0) #4
define i64 @fcmp_constant_inputs_true() {
%result = call i64 @llvm.amdgcn.fcmp.f32(float 2.0, float 4.0, i32 4)
ret i64 %result
@@ -1536,3 +1536,5 @@ define i64 @fcmp_constant_to_rhs_olt(float %x) {
%result = call i64 @llvm.amdgcn.fcmp.f32(float 4.0, float %x, i32 4)
ret i64 %result
}
+
+; CHECK: attributes #4 = { convergent }
diff --git a/test/Transforms/InstCombine/and-or-icmps.ll b/test/Transforms/InstCombine/and-or-icmps.ll
index e3aeee293139..464f390f988f 100644
--- a/test/Transforms/InstCombine/and-or-icmps.ll
+++ b/test/Transforms/InstCombine/and-or-icmps.ll
@@ -3,10 +3,8 @@
define i1 @PR1817_1(i32 %X) {
; CHECK-LABEL: @PR1817_1(
-; CHECK-NEXT: [[A:%.*]] = icmp slt i32 %X, 10
; CHECK-NEXT: [[B:%.*]] = icmp ult i32 %X, 10
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[B]]
;
%A = icmp slt i32 %X, 10
%B = icmp ult i32 %X, 10
diff --git a/test/Transforms/InstCombine/and-or-not.ll b/test/Transforms/InstCombine/and-or-not.ll
index 144e42e74868..a2e8a10735fd 100644
--- a/test/Transforms/InstCombine/and-or-not.ll
+++ b/test/Transforms/InstCombine/and-or-not.ll
@@ -2,55 +2,525 @@
; PR1510
-; These are all equivalent to A^B
-
-define i32 @test1(i32 %a, i32 %b) {
- %tmp3 = or i32 %b, %a ; <i32> [#uses=1]
- %tmp3not = xor i32 %tmp3, -1 ; <i32> [#uses=1]
- %tmp6 = and i32 %b, %a ; <i32> [#uses=1]
- %tmp7 = or i32 %tmp6, %tmp3not ; <i32> [#uses=1]
- %tmp7not = xor i32 %tmp7, -1 ; <i32> [#uses=1]
- ret i32 %tmp7not
-
-; CHECK-LABEL: @test1(
-; CHECK-NEXT: [[TMP7NOT:%.*]] = xor i32 %b, %a
-; CHECK-NEXT: ret i32 [[TMP7NOT]]
-}
-
-define i32 @test2(i32 %a, i32 %b) {
- %tmp3 = or i32 %b, %a ; <i32> [#uses=1]
- %tmp6 = and i32 %b, %a ; <i32> [#uses=1]
- %tmp6not = xor i32 %tmp6, -1 ; <i32> [#uses=1]
- %tmp7 = and i32 %tmp3, %tmp6not ; <i32> [#uses=1]
- ret i32 %tmp7
-
-; CHECK-LABEL: @test2(
-; CHECK-NEXT: [[TMP7:%.*]] = xor i32 %b, %a
-; CHECK-NEXT: ret i32 [[TMP7]]
-}
-
-define <4 x i32> @test3(<4 x i32> %a, <4 x i32> %b) {
- %tmp3 = or <4 x i32> %a, %b ; <<4 x i32>> [#uses=1]
- %tmp3not = xor <4 x i32> %tmp3, < i32 -1, i32 -1, i32 -1, i32 -1 > ; <<4 x i32>> [#uses=1]
- %tmp6 = and <4 x i32> %a, %b ; <<4 x i32>> [#uses=1]
- %tmp7 = or <4 x i32> %tmp6, %tmp3not ; <<4 x i32>> [#uses=1]
- %tmp7not = xor <4 x i32> %tmp7, < i32 -1, i32 -1, i32 -1, i32 -1 > ; <<4 x i32>> [#uses=1]
- ret <4 x i32> %tmp7not
-
-; CHECK-LABEL: @test3(
-; CHECK-NEXT: [[TMP7NOT:%.*]] = xor <4 x i32> %a, %b
-; CHECK-NEXT: ret <4 x i32> [[TMP7NOT]]
-}
-
-define <4 x i32> @test4(<4 x i32> %a, <4 x i32> %b) {
- %tmp3 = or <4 x i32> %a, %b ; <<4 x i32>> [#uses=1]
- %tmp6 = and <4 x i32> %a, %b ; <<4 x i32>> [#uses=1]
- %tmp6not = xor <4 x i32> %tmp6, < i32 -1, i32 -1, i32 -1, i32 -1 > ; <<4 x i32>> [#uses=1]
- %tmp7 = and <4 x i32> %tmp3, %tmp6not ; <<4 x i32>> [#uses=1]
- ret <4 x i32> %tmp7
-
-; CHECK-LABEL: @test4(
-; CHECK-NEXT: [[TMP7:%.*]] = xor <4 x i32> %a, %b
-; CHECK-NEXT: ret <4 x i32> [[TMP7]]
+; (a | b) & ~(a & b) --> a ^ b
+
+define i32 @and_to_xor1(i32 %a, i32 %b) {
+; CHECK-LABEL: @and_to_xor1(
+; CHECK-NEXT: [[AND2:%.*]] = xor i32 %a, %b
+; CHECK-NEXT: ret i32 [[AND2]]
+;
+ %or = or i32 %a, %b
+ %and = and i32 %a, %b
+ %not = xor i32 %and, -1
+ %and2 = and i32 %or, %not
+ ret i32 %and2
+}
+
+; ~(a & b) & (a | b) --> a ^ b
+
+define i32 @and_to_xor2(i32 %a, i32 %b) {
+; CHECK-LABEL: @and_to_xor2(
+; CHECK-NEXT: [[AND2:%.*]] = xor i32 %a, %b
+; CHECK-NEXT: ret i32 [[AND2]]
+;
+ %or = or i32 %a, %b
+ %and = and i32 %a, %b
+ %not = xor i32 %and, -1
+ %and2 = and i32 %not, %or
+ ret i32 %and2
+}
+
+; (a | b) & ~(b & a) --> a ^ b
+
+define i32 @and_to_xor3(i32 %a, i32 %b) {
+; CHECK-LABEL: @and_to_xor3(
+; CHECK-NEXT: [[AND2:%.*]] = xor i32 %a, %b
+; CHECK-NEXT: ret i32 [[AND2]]
+;
+ %or = or i32 %a, %b
+ %and = and i32 %b, %a
+ %not = xor i32 %and, -1
+ %and2 = and i32 %or, %not
+ ret i32 %and2
+}
+
+; ~(a & b) & (b | a) --> a ^ b
+
+define i32 @and_to_xor4(i32 %a, i32 %b) {
+; CHECK-LABEL: @and_to_xor4(
+; CHECK-NEXT: [[AND2:%.*]] = xor i32 %b, %a
+; CHECK-NEXT: ret i32 [[AND2]]
+;
+ %or = or i32 %b, %a
+ %and = and i32 %a, %b
+ %not = xor i32 %and, -1
+ %and2 = and i32 %not, %or
+ ret i32 %and2
+}
+
+define <4 x i32> @and_to_xor1_vec(<4 x i32> %a, <4 x i32> %b) {
+; CHECK-LABEL: @and_to_xor1_vec(
+; CHECK-NEXT: [[AND2:%.*]] = xor <4 x i32> %a, %b
+; CHECK-NEXT: ret <4 x i32> [[AND2]]
+;
+ %or = or <4 x i32> %a, %b
+ %and = and <4 x i32> %a, %b
+ %not = xor <4 x i32> %and, < i32 -1, i32 -1, i32 -1, i32 -1 >
+ %and2 = and <4 x i32> %or, %not
+ ret <4 x i32> %and2
+}
+
+; In the next 4 tests, cast instructions are used to thwart operand complexity
+; canonicalizations, so we can test all of the commuted patterns.
+
+; (a | ~b) & (~a | b) --> ~(a ^ b)
+
+define i32 @and_to_nxor1(float %fa, float %fb) {
+; CHECK-LABEL: @and_to_nxor1(
+; CHECK-NEXT: [[A:%.*]] = fptosi float %fa to i32
+; CHECK-NEXT: [[B:%.*]] = fptosi float %fb to i32
+; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A]], [[B]]
+; CHECK-NEXT: [[AND:%.*]] = xor i32 [[TMP1]], -1
+; CHECK-NEXT: ret i32 [[AND]]
+;
+ %a = fptosi float %fa to i32
+ %b = fptosi float %fb to i32
+ %nota = xor i32 %a, -1
+ %notb = xor i32 %b, -1
+ %or1 = or i32 %a, %notb
+ %or2 = or i32 %nota, %b
+ %and = and i32 %or1, %or2
+ ret i32 %and
+}
+
+; (a | ~b) & (b | ~a) --> ~(a ^ b)
+
+define i32 @and_to_nxor2(float %fa, float %fb) {
+; CHECK-LABEL: @and_to_nxor2(
+; CHECK-NEXT: [[A:%.*]] = fptosi float %fa to i32
+; CHECK-NEXT: [[B:%.*]] = fptosi float %fb to i32
+; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A]], [[B]]
+; CHECK-NEXT: [[AND:%.*]] = xor i32 [[TMP1]], -1
+; CHECK-NEXT: ret i32 [[AND]]
+;
+ %a = fptosi float %fa to i32
+ %b = fptosi float %fb to i32
+ %nota = xor i32 %a, -1
+ %notb = xor i32 %b, -1
+ %or1 = or i32 %a, %notb
+ %or2 = or i32 %b, %nota
+ %and = and i32 %or1, %or2
+ ret i32 %and
+}
+
+; (~a | b) & (a | ~b) --> ~(a ^ b)
+
+define i32 @and_to_nxor3(float %fa, float %fb) {
+; CHECK-LABEL: @and_to_nxor3(
+; CHECK-NEXT: [[A:%.*]] = fptosi float %fa to i32
+; CHECK-NEXT: [[B:%.*]] = fptosi float %fb to i32
+; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[A]]
+; CHECK-NEXT: [[AND:%.*]] = xor i32 [[TMP1]], -1
+; CHECK-NEXT: ret i32 [[AND]]
+;
+ %a = fptosi float %fa to i32
+ %b = fptosi float %fb to i32
+ %nota = xor i32 %a, -1
+ %notb = xor i32 %b, -1
+ %or1 = or i32 %nota, %b
+ %or2 = or i32 %a, %notb
+ %and = and i32 %or1, %or2
+ ret i32 %and
+}
+
+; (~a | b) & (~b | a) --> ~(a ^ b)
+
+define i32 @and_to_nxor4(float %fa, float %fb) {
+; CHECK-LABEL: @and_to_nxor4(
+; CHECK-NEXT: [[A:%.*]] = fptosi float %fa to i32
+; CHECK-NEXT: [[B:%.*]] = fptosi float %fb to i32
+; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[A]]
+; CHECK-NEXT: [[AND:%.*]] = xor i32 [[TMP1]], -1
+; CHECK-NEXT: ret i32 [[AND]]
+;
+ %a = fptosi float %fa to i32
+ %b = fptosi float %fb to i32
+ %nota = xor i32 %a, -1
+ %notb = xor i32 %b, -1
+ %or1 = or i32 %nota, %b
+ %or2 = or i32 %notb, %a
+ %and = and i32 %or1, %or2
+ ret i32 %and
+}
+
+; (a & ~b) | (~a & b) --> a ^ b
+
+define i32 @or_to_xor1(float %fa, float %fb) {
+; CHECK-LABEL: @or_to_xor1(
+; CHECK-NEXT: [[A:%.*]] = fptosi float %fa to i32
+; CHECK-NEXT: [[B:%.*]] = fptosi float %fb to i32
+; CHECK-NEXT: [[OR:%.*]] = xor i32 [[A]], [[B]]
+; CHECK-NEXT: ret i32 [[OR]]
+;
+ %a = fptosi float %fa to i32
+ %b = fptosi float %fb to i32
+ %nota = xor i32 %a, -1
+ %notb = xor i32 %b, -1
+ %and1 = and i32 %a, %notb
+ %and2 = and i32 %nota, %b
+ %or = or i32 %and1, %and2
+ ret i32 %or
+}
+
+; (a & ~b) | (b & ~a) --> a ^ b
+
+define i32 @or_to_xor2(float %fa, float %fb) {
+; CHECK-LABEL: @or_to_xor2(
+; CHECK-NEXT: [[A:%.*]] = fptosi float %fa to i32
+; CHECK-NEXT: [[B:%.*]] = fptosi float %fb to i32
+; CHECK-NEXT: [[OR:%.*]] = xor i32 [[A]], [[B]]
+; CHECK-NEXT: ret i32 [[OR]]
+;
+ %a = fptosi float %fa to i32
+ %b = fptosi float %fb to i32
+ %nota = xor i32 %a, -1
+ %notb = xor i32 %b, -1
+ %and1 = and i32 %a, %notb
+ %and2 = and i32 %b, %nota
+ %or = or i32 %and1, %and2
+ ret i32 %or
+}
+
+; (~a & b) | (~b & a) --> a ^ b
+
+define i32 @or_to_xor3(float %fa, float %fb) {
+; CHECK-LABEL: @or_to_xor3(
+; CHECK-NEXT: [[A:%.*]] = fptosi float %fa to i32
+; CHECK-NEXT: [[B:%.*]] = fptosi float %fb to i32
+; CHECK-NEXT: [[OR:%.*]] = xor i32 [[B]], [[A]]
+; CHECK-NEXT: ret i32 [[OR]]
+;
+ %a = fptosi float %fa to i32
+ %b = fptosi float %fb to i32
+ %nota = xor i32 %a, -1
+ %notb = xor i32 %b, -1
+ %and1 = and i32 %nota, %b
+ %and2 = and i32 %notb, %a
+ %or = or i32 %and1, %and2
+ ret i32 %or
+}
+
+; (~a & b) | (a & ~b) --> a ^ b
+
+define i32 @or_to_xor4(float %fa, float %fb) {
+; CHECK-LABEL: @or_to_xor4(
+; CHECK-NEXT: [[A:%.*]] = fptosi float %fa to i32
+; CHECK-NEXT: [[B:%.*]] = fptosi float %fb to i32
+; CHECK-NEXT: [[OR:%.*]] = xor i32 [[B]], [[A]]
+; CHECK-NEXT: ret i32 [[OR]]
+;
+ %a = fptosi float %fa to i32
+ %b = fptosi float %fb to i32
+ %nota = xor i32 %a, -1
+ %notb = xor i32 %b, -1
+ %and1 = and i32 %nota, %b
+ %and2 = and i32 %a, %notb
+ %or = or i32 %and1, %and2
+ ret i32 %or
+}
+
+; (a & b) | ~(a | b) --> ~(a ^ b)
+
+define i32 @or_to_nxor1(i32 %a, i32 %b) {
+; CHECK-LABEL: @or_to_nxor1(
+; CHECK-NEXT: [[TMP1:%.*]] = xor i32 %a, %b
+; CHECK-NEXT: [[OR2:%.*]] = xor i32 [[TMP1]], -1
+; CHECK-NEXT: ret i32 [[OR2]]
+;
+ %and = and i32 %a, %b
+ %or = or i32 %a, %b
+ %notor = xor i32 %or, -1
+ %or2 = or i32 %and, %notor
+ ret i32 %or2
+}
+
+; (a & b) | ~(b | a) --> ~(a ^ b)
+
+define i32 @or_to_nxor2(i32 %a, i32 %b) {
+; CHECK-LABEL: @or_to_nxor2(
+; CHECK-NEXT: [[TMP1:%.*]] = xor i32 %a, %b
+; CHECK-NEXT: [[OR2:%.*]] = xor i32 [[TMP1]], -1
+; CHECK-NEXT: ret i32 [[OR2]]
+;
+ %and = and i32 %a, %b
+ %or = or i32 %b, %a
+ %notor = xor i32 %or, -1
+ %or2 = or i32 %and, %notor
+ ret i32 %or2
+}
+
+; ~(a | b) | (a & b) --> ~(a ^ b)
+
+define i32 @or_to_nxor3(i32 %a, i32 %b) {
+; CHECK-LABEL: @or_to_nxor3(
+; CHECK-NEXT: [[TMP1:%.*]] = xor i32 %a, %b
+; CHECK-NEXT: [[OR2:%.*]] = xor i32 [[TMP1]], -1
+; CHECK-NEXT: ret i32 [[OR2]]
+;
+ %and = and i32 %a, %b
+ %or = or i32 %a, %b
+ %notor = xor i32 %or, -1
+ %or2 = or i32 %notor, %and
+ ret i32 %or2
+}
+
+; ~(a | b) | (b & a) --> ~(a ^ b)
+
+define i32 @or_to_nxor4(i32 %a, i32 %b) {
+; CHECK-LABEL: @or_to_nxor4(
+; CHECK-NEXT: [[TMP1:%.*]] = xor i32 %b, %a
+; CHECK-NEXT: [[OR2:%.*]] = xor i32 [[TMP1]], -1
+; CHECK-NEXT: ret i32 [[OR2]]
+;
+ %and = and i32 %b, %a
+ %or = or i32 %a, %b
+ %notor = xor i32 %or, -1
+ %or2 = or i32 %notor, %and
+ ret i32 %or2
+}
+
+; (a & b) ^ (a | b) --> a ^ b
+
+define i32 @xor_to_xor1(i32 %a, i32 %b) {
+; CHECK-LABEL: @xor_to_xor1(
+; CHECK-NEXT: [[XOR:%.*]] = xor i32 %a, %b
+; CHECK-NEXT: ret i32 [[XOR]]
+;
+ %and = and i32 %a, %b
+ %or = or i32 %a, %b
+ %xor = xor i32 %and, %or
+ ret i32 %xor
+}
+
+; (a & b) ^ (b | a) --> a ^ b
+
+define i32 @xor_to_xor2(i32 %a, i32 %b) {
+; CHECK-LABEL: @xor_to_xor2(
+; CHECK-NEXT: [[XOR:%.*]] = xor i32 %a, %b
+; CHECK-NEXT: ret i32 [[XOR]]
+;
+ %and = and i32 %a, %b
+ %or = or i32 %b, %a
+ %xor = xor i32 %and, %or
+ ret i32 %xor
+}
+
+; (a | b) ^ (a & b) --> a ^ b
+
+define i32 @xor_to_xor3(i32 %a, i32 %b) {
+; CHECK-LABEL: @xor_to_xor3(
+; CHECK-NEXT: [[XOR:%.*]] = xor i32 %a, %b
+; CHECK-NEXT: ret i32 [[XOR]]
+;
+ %or = or i32 %a, %b
+ %and = and i32 %a, %b
+ %xor = xor i32 %or, %and
+ ret i32 %xor
+}
+
+; (a | b) ^ (b & a) --> a ^ b
+
+define i32 @xor_to_xor4(i32 %a, i32 %b) {
+; CHECK-LABEL: @xor_to_xor4(
+; CHECK-NEXT: [[XOR:%.*]] = xor i32 %a, %b
+; CHECK-NEXT: ret i32 [[XOR]]
+;
+ %or = or i32 %a, %b
+ %and = and i32 %b, %a
+ %xor = xor i32 %or, %and
+ ret i32 %xor
+}
+
+; (a | ~b) ^ (~a | b) --> a ^ b
+
+; In the next 8 tests, cast instructions are used to thwart operand complexity
+; canonicalizations, so we can test all of the commuted patterns.
+
+define i32 @xor_to_xor5(float %fa, float %fb) {
+; CHECK-LABEL: @xor_to_xor5(
+; CHECK-NEXT: [[A:%.*]] = fptosi float %fa to i32
+; CHECK-NEXT: [[B:%.*]] = fptosi float %fb to i32
+; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A]], [[B]]
+; CHECK-NEXT: ret i32 [[XOR]]
+;
+ %a = fptosi float %fa to i32
+ %b = fptosi float %fb to i32
+ %nota = xor i32 %a, -1
+ %notb = xor i32 %b, -1
+ %or1 = or i32 %a, %notb
+ %or2 = or i32 %nota, %b
+ %xor = xor i32 %or1, %or2
+ ret i32 %xor
+}
+
+; (a | ~b) ^ (b | ~a) --> a ^ b
+
+define i32 @xor_to_xor6(float %fa, float %fb) {
+; CHECK-LABEL: @xor_to_xor6(
+; CHECK-NEXT: [[A:%.*]] = fptosi float %fa to i32
+; CHECK-NEXT: [[B:%.*]] = fptosi float %fb to i32
+; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[B]], [[A]]
+; CHECK-NEXT: ret i32 [[XOR]]
+;
+ %a = fptosi float %fa to i32
+ %b = fptosi float %fb to i32
+ %nota = xor i32 %a, -1
+ %notb = xor i32 %b, -1
+ %or1 = or i32 %a, %notb
+ %or2 = or i32 %b, %nota
+ %xor = xor i32 %or1, %or2
+ ret i32 %xor
+}
+
+; (~a | b) ^ (a | ~b) --> a ^ b
+
+define i32 @xor_to_xor7(float %fa, float %fb) {
+; CHECK-LABEL: @xor_to_xor7(
+; CHECK-NEXT: [[A:%.*]] = fptosi float %fa to i32
+; CHECK-NEXT: [[B:%.*]] = fptosi float %fb to i32
+; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A]], [[B]]
+; CHECK-NEXT: ret i32 [[XOR]]
+;
+ %a = fptosi float %fa to i32
+ %b = fptosi float %fb to i32
+ %nota = xor i32 %a, -1
+ %notb = xor i32 %b, -1
+ %or1 = or i32 %a, %notb
+ %or2 = or i32 %nota, %b
+ %xor = xor i32 %or2, %or1
+ ret i32 %xor
+}
+
+; (~a | b) ^ (~b | a) --> a ^ b
+
+define i32 @xor_to_xor8(float %fa, float %fb) {
+; CHECK-LABEL: @xor_to_xor8(
+; CHECK-NEXT: [[A:%.*]] = fptosi float %fa to i32
+; CHECK-NEXT: [[B:%.*]] = fptosi float %fb to i32
+; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[B]], [[A]]
+; CHECK-NEXT: ret i32 [[XOR]]
+;
+ %a = fptosi float %fa to i32
+ %b = fptosi float %fb to i32
+ %nota = xor i32 %a, -1
+ %notb = xor i32 %b, -1
+ %or1 = or i32 %notb, %a
+ %or2 = or i32 %nota, %b
+ %xor = xor i32 %or2, %or1
+ ret i32 %xor
+}
+
+; (a & ~b) ^ (~a & b) --> a ^ b
+
+define i32 @xor_to_xor9(float %fa, float %fb) {
+; CHECK-LABEL: @xor_to_xor9(
+; CHECK-NEXT: [[A:%.*]] = fptosi float %fa to i32
+; CHECK-NEXT: [[B:%.*]] = fptosi float %fb to i32
+; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A]], [[B]]
+; CHECK-NEXT: ret i32 [[XOR]]
+;
+ %a = fptosi float %fa to i32
+ %b = fptosi float %fb to i32
+ %nota = xor i32 %a, -1
+ %notb = xor i32 %b, -1
+ %and1 = and i32 %a, %notb
+ %and2 = and i32 %nota, %b
+ %xor = xor i32 %and1, %and2
+ ret i32 %xor
+}
+
+; (a & ~b) ^ (b & ~a) --> a ^ b
+
+define i32 @xor_to_xor10(float %fa, float %fb) {
+; CHECK-LABEL: @xor_to_xor10(
+; CHECK-NEXT: [[A:%.*]] = fptosi float %fa to i32
+; CHECK-NEXT: [[B:%.*]] = fptosi float %fb to i32
+; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[B]], [[A]]
+; CHECK-NEXT: ret i32 [[XOR]]
+;
+ %a = fptosi float %fa to i32
+ %b = fptosi float %fb to i32
+ %nota = xor i32 %a, -1
+ %notb = xor i32 %b, -1
+ %and1 = and i32 %a, %notb
+ %and2 = and i32 %b, %nota
+ %xor = xor i32 %and1, %and2
+ ret i32 %xor
+}
+
+; (~a & b) ^ (a & ~b) --> a ^ b
+
+define i32 @xor_to_xor11(float %fa, float %fb) {
+; CHECK-LABEL: @xor_to_xor11(
+; CHECK-NEXT: [[A:%.*]] = fptosi float %fa to i32
+; CHECK-NEXT: [[B:%.*]] = fptosi float %fb to i32
+; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A]], [[B]]
+; CHECK-NEXT: ret i32 [[XOR]]
+;
+ %a = fptosi float %fa to i32
+ %b = fptosi float %fb to i32
+ %nota = xor i32 %a, -1
+ %notb = xor i32 %b, -1
+ %and1 = and i32 %a, %notb
+ %and2 = and i32 %nota, %b
+ %xor = xor i32 %and2, %and1
+ ret i32 %xor
+}
+
+; (~a & b) ^ (~b & a) --> a ^ b
+
+define i32 @xor_to_xor12(float %fa, float %fb) {
+; CHECK-LABEL: @xor_to_xor12(
+; CHECK-NEXT: [[A:%.*]] = fptosi float %fa to i32
+; CHECK-NEXT: [[B:%.*]] = fptosi float %fb to i32
+; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[B]], [[A]]
+; CHECK-NEXT: ret i32 [[XOR]]
+;
+ %a = fptosi float %fa to i32
+ %b = fptosi float %fb to i32
+ %nota = xor i32 %a, -1
+ %notb = xor i32 %b, -1
+ %and1 = and i32 %notb, %a
+ %and2 = and i32 %nota, %b
+ %xor = xor i32 %and2, %and1
+ ret i32 %xor
+}
+
+; ~(~(a | b) | (a & b)) --> (a | b) & ~(a & b) -> a ^ b
+
+define i32 @demorgan_plus_and_to_xor(i32 %a, i32 %b) {
+; CHECK-LABEL: @demorgan_plus_and_to_xor(
+; CHECK-NEXT: [[NOT:%.*]] = xor i32 %b, %a
+; CHECK-NEXT: ret i32 [[NOT]]
+;
+ %or = or i32 %b, %a
+ %notor = xor i32 %or, -1
+ %and = and i32 %b, %a
+ %or2 = or i32 %and, %notor
+ %not = xor i32 %or2, -1
+ ret i32 %not
+}
+
+define <4 x i32> @demorgan_plus_and_to_xor_vec(<4 x i32> %a, <4 x i32> %b) {
+; CHECK-LABEL: @demorgan_plus_and_to_xor_vec(
+; CHECK-NEXT: [[NOT:%.*]] = xor <4 x i32> %a, %b
+; CHECK-NEXT: ret <4 x i32> [[NOT]]
+;
+ %or = or <4 x i32> %a, %b
+ %notor = xor <4 x i32> %or, < i32 -1, i32 -1, i32 -1, i32 -1 >
+ %and = and <4 x i32> %a, %b
+ %or2 = or <4 x i32> %and, %notor
+ %not = xor <4 x i32> %or2, < i32 -1, i32 -1, i32 -1, i32 -1 >
+ ret <4 x i32> %not
}
diff --git a/test/Transforms/InstCombine/and.ll b/test/Transforms/InstCombine/and.ll
index 9a4d1e5758b3..a2715c12fa88 100644
--- a/test/Transforms/InstCombine/and.ll
+++ b/test/Transforms/InstCombine/and.ll
@@ -613,3 +613,31 @@ final:
%value = and <2 x i32> %A, <i32 123, i32 333>
ret <2 x i32> %value
}
+
+define i32 @test42(i32 %a, i32 %c, i32 %d) {
+; CHECK-LABEL: @test42(
+; CHECK-NEXT: [[FORCE:%.*]] = mul i32 [[C:%.*]], [[D:%.*]]
+; CHECK-NEXT: [[AND:%.*]] = and i32 [[FORCE]], [[A:%.*]]
+; CHECK-NEXT: ret i32 [[AND]]
+;
+ %force = mul i32 %c, %d ; forces the complexity sorting
+ %or = or i32 %a, %force
+ %nota = xor i32 %a, -1
+ %xor = xor i32 %nota, %force
+ %and = and i32 %xor, %or
+ ret i32 %and
+}
+
+define i32 @test43(i32 %a, i32 %c, i32 %d) {
+; CHECK-LABEL: @test43(
+; CHECK-NEXT: [[FORCE:%.*]] = mul i32 [[C:%.*]], [[D:%.*]]
+; CHECK-NEXT: [[AND:%.*]] = and i32 [[FORCE]], [[A:%.*]]
+; CHECK-NEXT: ret i32 [[AND]]
+;
+ %force = mul i32 %c, %d ; forces the complexity sorting
+ %or = or i32 %a, %force
+ %nota = xor i32 %a, -1
+ %xor = xor i32 %nota, %force
+ %and = and i32 %or, %xor
+ ret i32 %and
+}
diff --git a/test/Transforms/InstCombine/apint-shift.ll b/test/Transforms/InstCombine/apint-shift.ll
index f339de35d77c..679a87a7efbc 100644
--- a/test/Transforms/InstCombine/apint-shift.ll
+++ b/test/Transforms/InstCombine/apint-shift.ll
@@ -287,13 +287,10 @@ define i47 @test12(i47 %X) {
ret i47 %sh2
}
-; FIXME: Same as above with vectors.
-
define <2 x i47> @test12_splat_vec(<2 x i47> %X) {
; CHECK-LABEL: @test12_splat_vec(
-; CHECK-NEXT: [[SH1:%.*]] = ashr <2 x i47> %X, <i47 8, i47 8>
-; CHECK-NEXT: [[SH2:%.*]] = shl nsw <2 x i47> [[SH1]], <i47 8, i47 8>
-; CHECK-NEXT: ret <2 x i47> [[SH2]]
+; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i47> %X, <i47 -256, i47 -256>
+; CHECK-NEXT: ret <2 x i47> [[TMP1]]
;
%sh1 = ashr <2 x i47> %X, <i47 8, i47 8>
%sh2 = shl <2 x i47> %sh1, <i47 8, i47 8>
diff --git a/test/Transforms/InstCombine/debuginfo-dce.ll b/test/Transforms/InstCombine/debuginfo-dce.ll
index e23aef7334d5..58e9d7d767e9 100644
--- a/test/Transforms/InstCombine/debuginfo-dce.ll
+++ b/test/Transforms/InstCombine/debuginfo-dce.ll
@@ -23,7 +23,6 @@ target triple = "x86_64-apple-macosx10.12.0"
%struct.entry = type { %struct.entry* }
-; Function Attrs: nounwind ssp uwtable
define void @salvage_load(%struct.entry** %queue) local_unnamed_addr #0 !dbg !14 {
entry:
%im_not_dead = alloca %struct.entry*
@@ -38,7 +37,6 @@ entry:
ret void, !dbg !21
}
-; Function Attrs: nounwind ssp uwtable
define void @salvage_bitcast(%struct.entry* %queue) local_unnamed_addr #0 !dbg !14 {
entry:
%im_not_dead = alloca i8*
@@ -53,24 +51,54 @@ entry:
ret void, !dbg !21
}
-; Function Attrs: nounwind ssp uwtable
-define void @salvage_gep(%struct.entry* %queue, %struct.entry* %end) local_unnamed_addr #0 !dbg !14 {
+define void @salvage_gep0(%struct.entry* %queue, %struct.entry* %end) local_unnamed_addr #0 !dbg !14 {
entry:
%im_not_dead = alloca %struct.entry**
%0 = getelementptr inbounds %struct.entry, %struct.entry* %queue, i32 -1, i32 0, !dbg !19
%1 = getelementptr inbounds %struct.entry, %struct.entry* %queue, i32 -1, i32 0, !dbg !19
call void @llvm.dbg.value(metadata %struct.entry** %1, i64 0, metadata !18, metadata !20), !dbg !19
-; CHECK: define void @salvage_gep
+; CHECK: define void @salvage_gep0
; CHECK-NEXT: entry:
; CHECK-NEXT: call void @llvm.dbg.value(metadata %struct.entry* %queue, i64 0,
-; CHECK-SAME: metadata ![[GEP_EXPR:[0-9]+]])
+; CHECK-SAME: metadata ![[GEP0_EXPR:[0-9]+]])
+ store %struct.entry** %1, %struct.entry*** %im_not_dead, align 8
+ ret void, !dbg !21
+}
+
+define void @salvage_gep1(%struct.entry* %queue, %struct.entry* %end) local_unnamed_addr #0 !dbg !14 {
+entry:
+ %im_not_dead = alloca %struct.entry**
+ %0 = getelementptr inbounds %struct.entry, %struct.entry* %queue, i32 -1, i32 0, !dbg !19
+ %1 = getelementptr inbounds %struct.entry, %struct.entry* %queue, i32 -1, i32 0, !dbg !19
+ call void @llvm.dbg.value(metadata %struct.entry** %1, i64 0, metadata !18, metadata !DIExpression(DW_OP_LLVM_fragment, 0, 32)), !dbg !19
+; CHECK: define void @salvage_gep1
+; CHECK-NEXT: entry:
+; CHECK-NEXT: call void @llvm.dbg.value(metadata %struct.entry* %queue, i64 0,
+; CHECK-SAME: metadata ![[GEP1_EXPR:[0-9]+]])
+ store %struct.entry** %1, %struct.entry*** %im_not_dead, align 8
+ ret void, !dbg !21
+}
+
+define void @salvage_gep2(%struct.entry* %queue, %struct.entry* %end) local_unnamed_addr #0 !dbg !14 {
+entry:
+ %im_not_dead = alloca %struct.entry**
+ %0 = getelementptr inbounds %struct.entry, %struct.entry* %queue, i32 -1, i32 0, !dbg !19
+ %1 = getelementptr inbounds %struct.entry, %struct.entry* %queue, i32 -1, i32 0, !dbg !19
+ call void @llvm.dbg.value(metadata %struct.entry** %1, i64 0, metadata !18, metadata !DIExpression(DW_OP_stack_value)), !dbg !19
+; CHECK: define void @salvage_gep2
+; CHECK-NEXT: entry:
+; CHECK-NEXT: call void @llvm.dbg.value(metadata %struct.entry* %queue, i64 0,
+; CHECK-SAME: metadata ![[GEP2_EXPR:[0-9]+]])
store %struct.entry** %1, %struct.entry*** %im_not_dead, align 8
ret void, !dbg !21
}
; CHECK: ![[LOAD_EXPR]] = !DIExpression(DW_OP_deref, DW_OP_plus, 0)
; CHECK: ![[BITCAST_EXPR]] = !DIExpression(DW_OP_plus, 0)
-; CHECK: ![[GEP_EXPR]] = !DIExpression(DW_OP_minus, 8, DW_OP_plus, 0)
+; CHECK: ![[GEP0_EXPR]] = !DIExpression(DW_OP_minus, 8, DW_OP_plus, 0, DW_OP_stack_value)
+; CHECK: ![[GEP1_EXPR]] = !DIExpression(DW_OP_minus, 8, DW_OP_stack_value,
+; CHECK-SAME: DW_OP_LLVM_fragment, 0, 32)
+; CHECK: ![[GEP2_EXPR]] = !DIExpression(DW_OP_minus, 8, DW_OP_stack_value)
; Function Attrs: nounwind readnone
declare void @llvm.dbg.value(metadata, i64, metadata, metadata) #1
diff --git a/test/Transforms/InstCombine/fsub.ll b/test/Transforms/InstCombine/fsub.ll
index af2fadd2867b..6b62f5dd7e38 100644
--- a/test/Transforms/InstCombine/fsub.ll
+++ b/test/Transforms/InstCombine/fsub.ll
@@ -21,3 +21,47 @@ define double @test2(double %x, double %y) nounwind {
ret double %t2
}
+
+; CHECK-LABEL: @fsub_undef(
+; CHECK: %sub = fsub float %val, undef
+define float @fsub_undef(float %val) {
+bb:
+ %sub = fsub float %val, undef
+ ret float %sub
+}
+
+; XXX - Why doesn't this fold to undef?
+; CHECK-LABEL: @fsub_fast_undef(
+; CHCK: %sub = fsub fast float %val, undef
+define float @fsub_fast_undef(float %val) {
+bb:
+ %sub = fsub fast float %val, undef
+ ret float %sub
+}
+
+; CHECK-LABEL: @fneg_undef(
+; CHECK: ret float fsub (float -0.000000e+00, float undef)
+define float @fneg_undef(float %val) {
+bb:
+ %sub = fsub float -0.0, undef
+ ret float %sub
+}
+
+; CHECK-LABEL: @fneg_fast_undef(
+; CHECK: ret float fsub (float -0.000000e+00, float undef)
+define float @fneg_fast_undef(float %val) {
+bb:
+ %sub = fsub fast float -0.0, undef
+ ret float %sub
+}
+
+; This folds to a constant expression, which produced 0 instructions
+; contrary to the expected one for negation.
+; CHECK-LABEL: @inconsistent_numbers_fsub_undef(
+; CHECK: ret float fsub (float -0.000000e+00, float undef)
+define float @inconsistent_numbers_fsub_undef(float %val) {
+bb:
+ %sub0 = fsub fast float %val, undef
+ %sub1 = fsub fast float %sub0, %val
+ ret float %sub1
+}
diff --git a/test/Transforms/InstCombine/intrinsics.ll b/test/Transforms/InstCombine/intrinsics.ll
index e8f5ddd329ff..b9e208440581 100644
--- a/test/Transforms/InstCombine/intrinsics.ll
+++ b/test/Transforms/InstCombine/intrinsics.ll
@@ -281,6 +281,19 @@ define i32 @cttz(i32 %a) {
ret i32 %count
}
+define i1 @cttz_knownbits(i32 %arg) {
+; CHECK-LABEL: @cttz_knownbits(
+; CHECK-NEXT: [[OR:%.*]] = or i32 [[ARG:%.*]], 4
+; CHECK-NEXT: [[CNT:%.*]] = call i32 @llvm.cttz.i32(i32 [[OR]], i1 true) #0
+; CHECK-NEXT: [[RES:%.*]] = icmp eq i32 [[CNT]], 4
+; CHECK-NEXT: ret i1 [[RES]]
+;
+ %or = or i32 %arg, 4
+ %cnt = call i32 @llvm.cttz.i32(i32 %or, i1 true) nounwind readnone
+ %res = icmp eq i32 %cnt, 4
+ ret i1 %res
+}
+
define i8 @ctlz(i8 %a) {
; CHECK-LABEL: @ctlz(
; CHECK-NEXT: ret i8 2
@@ -291,6 +304,19 @@ define i8 @ctlz(i8 %a) {
ret i8 %count
}
+define i1 @ctlz_knownbits(i8 %arg) {
+; CHECK-LABEL: @ctlz_knownbits(
+; CHECK-NEXT: [[OR:%.*]] = or i8 [[ARG:%.*]], 32
+; CHECK-NEXT: [[CNT:%.*]] = call i8 @llvm.ctlz.i8(i8 [[OR]], i1 true) #0
+; CHECK-NEXT: [[RES:%.*]] = icmp eq i8 [[CNT]], 4
+; CHECK-NEXT: ret i1 [[RES]]
+;
+ %or = or i8 %arg, 32
+ %cnt = call i8 @llvm.ctlz.i8(i8 %or, i1 true) nounwind readnone
+ %res = icmp eq i8 %cnt, 4
+ ret i1 %res
+}
+
define void @cmp.simplify(i32 %a, i32 %b, i1* %c) {
%lz = tail call i32 @llvm.ctlz.i32(i32 %a, i1 false) nounwind readnone
%lz.cmp = icmp eq i32 %lz, 32
diff --git a/test/Transforms/InstCombine/memset-1.ll b/test/Transforms/InstCombine/memset-1.ll
index 7310e5f4faf8..86f3afdef8dc 100644
--- a/test/Transforms/InstCombine/memset-1.ll
+++ b/test/Transforms/InstCombine/memset-1.ll
@@ -26,6 +26,15 @@ define i8* @pr25892_lite(i32 %size) #0 {
; CHECK-NEXT: ret i8* %calloc
}
+; This should not create a calloc and not crash the compiler.
+; CHECK-LABEL: @notmalloc_memset
+; CHECK-NOT: @calloc
+define i8* @notmalloc_memset(i32 %size, i8*(i32)* %notmalloc) {
+ %call1 = call i8* %notmalloc(i32 %size) #1
+ %call2 = call i8* @memset(i8* %call1, i32 0, i32 %size) #1
+ ret i8* %call2
+}
+
; FIXME: memset(malloc(x), 0, x) -> calloc(1, x)
; This doesn't fire currently because the malloc has more than one use.
diff --git a/test/Transforms/InstCombine/minmax-fold.ll b/test/Transforms/InstCombine/minmax-fold.ll
index 19a7341fdc28..f0e56426a8da 100644
--- a/test/Transforms/InstCombine/minmax-fold.ll
+++ b/test/Transforms/InstCombine/minmax-fold.ll
@@ -280,14 +280,10 @@ define i32 @test72(i32 %x) {
ret i32 %retval
}
-; FIXME - vector neglect: FoldAndOfICmps() / FoldOrOfICmps()
-
define <2 x i32> @test72vec(<2 x i32> %x) {
; CHECK-LABEL: @test72vec(
-; CHECK-NEXT: [[TMP1:%.*]] = icmp slt <2 x i32> %x, <i32 92, i32 92>
; CHECK-NEXT: [[TMP2:%.*]] = icmp slt <2 x i32> %x, <i32 11, i32 11>
-; CHECK-NEXT: [[TMP3:%.*]] = and <2 x i1> [[TMP1]], [[TMP2]]
-; CHECK-NEXT: [[RETVAL:%.*]] = select <2 x i1> [[TMP3]], <2 x i32> %x, <2 x i32> <i32 11, i32 11>
+; CHECK-NEXT: [[RETVAL:%.*]] = select <2 x i1> [[TMP2]], <2 x i32> %x, <2 x i32> <i32 11, i32 11>
; CHECK-NEXT: ret <2 x i32> [[RETVAL]]
;
%cmp = icmp sgt <2 x i32> %x, <i32 92, i32 92>
diff --git a/test/Transforms/InstCombine/or-to-xor.ll b/test/Transforms/InstCombine/or-to-xor.ll
deleted file mode 100644
index 84567906f843..000000000000
--- a/test/Transforms/InstCombine/or-to-xor.ll
+++ /dev/null
@@ -1,55 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt < %s -instcombine -S | FileCheck %s
-
-define i32 @func1(i32 %a, i32 %b) {
-; CHECK-LABEL: @func1(
-; CHECK-NEXT: [[T2:%.*]] = xor i32 %a, %b
-; CHECK-NEXT: ret i32 [[T2]]
-;
- %b_not = xor i32 %b, -1
- %t0 = and i32 %a, %b_not
- %a_not = xor i32 %a, -1
- %t1 = and i32 %a_not, %b
- %t2 = or i32 %t0, %t1
- ret i32 %t2
-}
-
-define i32 @func2(i32 %a, i32 %b) {
-; CHECK-LABEL: @func2(
-; CHECK-NEXT: [[T2:%.*]] = xor i32 %a, %b
-; CHECK-NEXT: ret i32 [[T2]]
-;
- %b_not = xor i32 %b, -1
- %t0 = and i32 %b_not, %a
- %a_not = xor i32 %a, -1
- %t1 = and i32 %a_not, %b
- %t2 = or i32 %t0, %t1
- ret i32 %t2
-}
-
-define i32 @func3(i32 %a, i32 %b) {
-; CHECK-LABEL: @func3(
-; CHECK-NEXT: [[T2:%.*]] = xor i32 %a, %b
-; CHECK-NEXT: ret i32 [[T2]]
-;
- %b_not = xor i32 %b, -1
- %t0 = and i32 %a, %b_not
- %a_not = xor i32 %a, -1
- %t1 = and i32 %b, %a_not
- %t2 = or i32 %t0, %t1
- ret i32 %t2
-}
-
-define i32 @func4(i32 %a, i32 %b) {
-; CHECK-LABEL: @func4(
-; CHECK-NEXT: [[T2:%.*]] = xor i32 %a, %b
-; CHECK-NEXT: ret i32 [[T2]]
-;
- %b_not = xor i32 %b, -1
- %t0 = and i32 %b_not, %a
- %a_not = xor i32 %a, -1
- %t1 = and i32 %b, %a_not
- %t2 = or i32 %t0, %t1
- ret i32 %t2
-}
-
diff --git a/test/Transforms/InstCombine/or.ll b/test/Transforms/InstCombine/or.ll
index 41e6d2d1f827..9ae5eafdfccf 100644
--- a/test/Transforms/InstCombine/or.ll
+++ b/test/Transforms/InstCombine/or.ll
@@ -619,59 +619,6 @@ define i32 @test42_commuted_xor(i32 %a, i32 %b) {
ret i32 %or
}
-; (A & ~B) | (A ^ B) -> A ^ B
-
-define i32 @test43(i32 %a, i32 %b) {
-; CHECK-LABEL: @test43(
-; CHECK-NEXT: [[OR:%.*]] = xor i32 %a, %b
-; CHECK-NEXT: ret i32 [[OR]]
-;
- %neg = xor i32 %b, -1
- %and = and i32 %a, %neg
- %xor = xor i32 %a, %b
- %or = or i32 %and, %xor
- ret i32 %or
-}
-
-define i32 @test43_commuted_and(i32 %a, i32 %b) {
-; CHECK-LABEL: @test43_commuted_and(
-; CHECK-NEXT: [[OR:%.*]] = xor i32 %a, %b
-; CHECK-NEXT: ret i32 [[OR]]
-;
- %neg = xor i32 %b, -1
- %and = and i32 %neg, %a
- %xor = xor i32 %a, %b
- %or = or i32 %and, %xor
- ret i32 %or
-}
-
-; Commute operands of the 'or'.
-; (A ^ B) | (A & ~B) -> A ^ B
-
-define i32 @test44(i32 %a, i32 %b) {
-; CHECK-LABEL: @test44(
-; CHECK-NEXT: [[OR:%.*]] = xor i32 %a, %b
-; CHECK-NEXT: ret i32 [[OR]]
-;
- %xor = xor i32 %a, %b
- %neg = xor i32 %b, -1
- %and = and i32 %a, %neg
- %or = or i32 %xor, %and
- ret i32 %or
-}
-
-define i32 @test44_commuted_and(i32 %a, i32 %b) {
-; CHECK-LABEL: @test44_commuted_and(
-; CHECK-NEXT: [[OR:%.*]] = xor i32 %a, %b
-; CHECK-NEXT: ret i32 [[OR]]
-;
- %xor = xor i32 %a, %b
- %neg = xor i32 %b, -1
- %and = and i32 %neg, %a
- %or = or i32 %xor, %and
- ret i32 %or
-}
-
define i32 @test45(i32 %x, i32 %y, i32 %z) {
; CHECK-LABEL: @test45(
; CHECK-NEXT: [[TMP1:%.*]] = and i32 %x, %z
diff --git a/test/Transforms/InstCombine/pr17827.ll b/test/Transforms/InstCombine/pr17827.ll
index ada6edab69c6..c9cbf764d7f5 100644
--- a/test/Transforms/InstCombine/pr17827.ll
+++ b/test/Transforms/InstCombine/pr17827.ll
@@ -52,9 +52,7 @@ define i1 @test_shift_and_cmp_changed1(i8 %p, i8 %q) {
define <2 x i1> @test_shift_and_cmp_changed1_vec(<2 x i8> %p, <2 x i8> %q) {
; CHECK-LABEL: @test_shift_and_cmp_changed1_vec(
; CHECK-NEXT: [[ANDP:%.*]] = and <2 x i8> %p, <i8 6, i8 6>
-; CHECK-NEXT: [[ANDQ:%.*]] = and <2 x i8> %q, <i8 8, i8 8>
-; CHECK-NEXT: [[OR:%.*]] = or <2 x i8> [[ANDQ]], [[ANDP]]
-; CHECK-NEXT: [[SHL:%.*]] = shl <2 x i8> [[OR]], <i8 5, i8 5>
+; CHECK-NEXT: [[SHL:%.*]] = shl nuw <2 x i8> [[ANDP]], <i8 5, i8 5>
; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[SHL]], <i8 32, i8 32>
; CHECK-NEXT: ret <2 x i1> [[CMP]]
;
diff --git a/test/Transforms/InstCombine/shift.ll b/test/Transforms/InstCombine/shift.ll
index d5f489280a03..ce8e2fcd38b9 100644
--- a/test/Transforms/InstCombine/shift.ll
+++ b/test/Transforms/InstCombine/shift.ll
@@ -1049,12 +1049,11 @@ define i8 @test53_no_nuw(i8 %x) {
}
; (X << C1) >>u C2 --> X << (C1 - C2) & (-1 >> C2)
-; FIXME: Demanded bits should change the mask constant as it does for the scalar case.
define <2 x i8> @test53_no_nuw_splat_vec(<2 x i8> %x) {
; CHECK-LABEL: @test53_no_nuw_splat_vec(
; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i8> %x, <i8 2, i8 2>
-; CHECK-NEXT: [[B:%.*]] = and <2 x i8> [[TMP1]], <i8 127, i8 127>
+; CHECK-NEXT: [[B:%.*]] = and <2 x i8> [[TMP1]], <i8 124, i8 124>
; CHECK-NEXT: ret <2 x i8> [[B]]
;
%A = shl <2 x i8> %x, <i8 3, i8 3>
@@ -1074,6 +1073,17 @@ define i32 @test54(i32 %x) {
ret i32 %and
}
+define <2 x i32> @test54_splat_vec(<2 x i32> %x) {
+; CHECK-LABEL: @test54_splat_vec(
+; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i32> %x, <i32 3, i32 3>
+; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[TMP1]], <i32 16, i32 16>
+; CHECK-NEXT: ret <2 x i32> [[AND]]
+;
+ %shr2 = lshr <2 x i32> %x, <i32 1, i32 1>
+ %shl = shl <2 x i32> %shr2, <i32 4, i32 4>
+ %and = and <2 x i32> %shl, <i32 16, i32 16>
+ ret <2 x i32> %and
+}
define i32 @test55(i32 %x) {
; CHECK-LABEL: @test55(
@@ -1100,7 +1110,6 @@ define i32 @test56(i32 %x) {
ret i32 %or
}
-
define i32 @test57(i32 %x) {
; CHECK-LABEL: @test57(
; CHECK-NEXT: [[SHR1:%.*]] = lshr i32 %x, 1
@@ -1114,7 +1123,6 @@ define i32 @test57(i32 %x) {
ret i32 %or
}
-
define i32 @test58(i32 %x) {
; CHECK-LABEL: @test58(
; CHECK-NEXT: [[TMP1:%.*]] = ashr i32 %x, 3
@@ -1127,6 +1135,17 @@ define i32 @test58(i32 %x) {
ret i32 %or
}
+define <2 x i32> @test58_splat_vec(<2 x i32> %x) {
+; CHECK-LABEL: @test58_splat_vec(
+; CHECK-NEXT: [[TMP1:%.*]] = ashr <2 x i32> %x, <i32 3, i32 3>
+; CHECK-NEXT: [[OR:%.*]] = or <2 x i32> [[TMP1]], <i32 1, i32 1>
+; CHECK-NEXT: ret <2 x i32> [[OR]]
+;
+ %shr = ashr <2 x i32> %x, <i32 4, i32 4>
+ %shl = shl <2 x i32> %shr, <i32 1, i32 1>
+ %or = or <2 x i32> %shl, <i32 1, i32 1>
+ ret <2 x i32> %or
+}
define i32 @test59(i32 %x) {
; CHECK-LABEL: @test59(
@@ -1257,8 +1276,7 @@ define i64 @test_64(i32 %t) {
define <2 x i64> @test_64_splat_vec(<2 x i32> %t) {
; CHECK-LABEL: @test_64_splat_vec(
-; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> %t, <i32 16777215, i32 16777215>
-; CHECK-NEXT: [[TMP1:%.*]] = shl nuw <2 x i32> [[AND]], <i32 8, i32 8>
+; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i32> %t, <i32 8, i32 8>
; CHECK-NEXT: [[SHL:%.*]] = zext <2 x i32> [[TMP1]] to <2 x i64>
; CHECK-NEXT: ret <2 x i64> [[SHL]]
;
diff --git a/test/Transforms/InstCombine/xor2.ll b/test/Transforms/InstCombine/xor2.ll
index 79e62723f143..f817ac5ca40c 100644
--- a/test/Transforms/InstCombine/xor2.ll
+++ b/test/Transforms/InstCombine/xor2.ll
@@ -191,6 +191,81 @@ define i32 @test11(i32 %A, i32 %B) {
ret i32 %and
}
+define i32 @test11b(i32 %A, i32 %B) {
+; CHECK-LABEL: @test11b(
+; CHECK-NEXT: ret i32 0
+;
+ %xor1 = xor i32 %B, %A
+ %not = xor i32 %A, -1
+ %xor2 = xor i32 %not, %B
+ %and = and i32 %xor2, %xor1
+ ret i32 %and
+}
+
+define i32 @test11c(i32 %A, i32 %B) {
+; CHECK-LABEL: @test11c(
+; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[A]], -1
+; CHECK-NEXT: [[XOR2:%.*]] = xor i32 [[NOT]], [[B]]
+; CHECK-NEXT: [[AND:%.*]] = and i32 [[XOR1]], [[XOR2]]
+; CHECK-NEXT: ret i32 [[AND]]
+;
+ %xor1 = xor i32 %A, %B
+ %not = xor i32 %A, -1
+ %xor2 = xor i32 %not, %B
+ %and = and i32 %xor1, %xor2
+ ret i32 %and
+}
+
+define i32 @test11d(i32 %A, i32 %B) {
+; CHECK-LABEL: @test11d(
+; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[A]], -1
+; CHECK-NEXT: [[XOR2:%.*]] = xor i32 [[NOT]], [[B]]
+; CHECK-NEXT: [[AND:%.*]] = and i32 [[XOR2]], [[XOR1]]
+; CHECK-NEXT: ret i32 [[AND]]
+;
+ %xor1 = xor i32 %A, %B
+ %not = xor i32 %A, -1
+ %xor2 = xor i32 %not, %B
+ %and = and i32 %xor2, %xor1
+ ret i32 %and
+}
+
+define i32 @test11e(i32 %A, i32 %B, i32 %C) {
+; CHECK-LABEL: @test11e(
+; CHECK-NEXT: [[FORCE:%.*]] = mul i32 [[B:%.*]], [[C:%.*]]
+; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[FORCE]], [[A:%.*]]
+; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[A]], -1
+; CHECK-NEXT: [[XOR2:%.*]] = xor i32 [[FORCE]], [[NOT]]
+; CHECK-NEXT: [[AND:%.*]] = and i32 [[XOR1]], [[XOR2]]
+; CHECK-NEXT: ret i32 [[AND]]
+;
+ %force = mul i32 %B, %C
+ %xor1 = xor i32 %force, %A
+ %not = xor i32 %A, -1
+ %xor2 = xor i32 %force, %not
+ %and = and i32 %xor1, %xor2
+ ret i32 %and
+}
+
+define i32 @test11f(i32 %A, i32 %B, i32 %C) {
+; CHECK-LABEL: @test11f(
+; CHECK-NEXT: [[FORCE:%.*]] = mul i32 [[B:%.*]], [[C:%.*]]
+; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[FORCE]], [[A:%.*]]
+; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[A]], -1
+; CHECK-NEXT: [[XOR2:%.*]] = xor i32 [[FORCE]], [[NOT]]
+; CHECK-NEXT: [[AND:%.*]] = and i32 [[XOR2]], [[XOR1]]
+; CHECK-NEXT: ret i32 [[AND]]
+;
+ %force = mul i32 %B, %C
+ %xor1 = xor i32 %force, %A
+ %not = xor i32 %A, -1
+ %xor2 = xor i32 %force, %not
+ %and = and i32 %xor2, %xor1
+ ret i32 %and
+}
+
define i32 @test12(i32 %a, i32 %b) {
; CHECK-LABEL: @test12(
; CHECK-NEXT: [[TMP1:%.*]] = and i32 %a, %b
diff --git a/test/Transforms/InstSimplify/AndOrXor.ll b/test/Transforms/InstSimplify/AndOrXor.ll
index aa71c6ba86ae..f9aaa4fa0c6c 100644
--- a/test/Transforms/InstSimplify/AndOrXor.ll
+++ b/test/Transforms/InstSimplify/AndOrXor.ll
@@ -468,3 +468,118 @@ define <2 x i3> @and_of_different_cast_icmps_vec(<2 x i8> %i, <2 x i16> %j) {
ret <2 x i3> %and
}
+; (A & ~B) | (A ^ B) -> A ^ B
+
+define i32 @test43(i32 %a, i32 %b) {
+; CHECK-LABEL: @test43(
+; CHECK-NEXT: [[OR:%.*]] = xor i32 %a, %b
+; CHECK-NEXT: ret i32 [[OR]]
+;
+ %neg = xor i32 %b, -1
+ %and = and i32 %a, %neg
+ %xor = xor i32 %a, %b
+ %or = or i32 %and, %xor
+ ret i32 %or
+}
+
+define i32 @test43_commuted_and(i32 %a, i32 %b) {
+; CHECK-LABEL: @test43_commuted_and(
+; CHECK-NEXT: [[OR:%.*]] = xor i32 %a, %b
+; CHECK-NEXT: ret i32 [[OR]]
+;
+ %neg = xor i32 %b, -1
+ %and = and i32 %neg, %a
+ %xor = xor i32 %a, %b
+ %or = or i32 %and, %xor
+ ret i32 %or
+}
+
+; Commute operands of the 'or'.
+; (A ^ B) | (A & ~B) -> A ^ B
+
+define i32 @test44(i32 %a, i32 %b) {
+; CHECK-LABEL: @test44(
+; CHECK-NEXT: [[OR:%.*]] = xor i32 %a, %b
+; CHECK-NEXT: ret i32 [[OR]]
+;
+ %xor = xor i32 %a, %b
+ %neg = xor i32 %b, -1
+ %and = and i32 %a, %neg
+ %or = or i32 %xor, %and
+ ret i32 %or
+}
+
+define i32 @test44_commuted_and(i32 %a, i32 %b) {
+; CHECK-LABEL: @test44_commuted_and(
+; CHECK-NEXT: [[OR:%.*]] = xor i32 %a, %b
+; CHECK-NEXT: ret i32 [[OR]]
+;
+ %xor = xor i32 %a, %b
+ %neg = xor i32 %b, -1
+ %and = and i32 %neg, %a
+ %or = or i32 %xor, %and
+ ret i32 %or
+}
+
+; (~A & ~B) | (~A ^ B) -> ~A ^ B
+
+define i32 @test45(i32 %a, i32 %b) {
+; CHECK-LABEL: @test45(
+; CHECK-NEXT: [[NEGB:%.*]] = xor i32 [[B:%.*]], -1
+; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A:%.*]], [[NEGB]]
+; CHECK-NEXT: ret i32 [[XOR]]
+;
+ %nega = xor i32 %a, -1
+ %negb = xor i32 %b, -1
+ %and = and i32 %nega, %negb
+ %xor = xor i32 %a, %negb
+ %or = or i32 %and, %xor
+ ret i32 %or
+}
+
+define i32 @test45_commuted_and(i32 %a, i32 %b) {
+; CHECK-LABEL: @test45_commuted_and(
+; CHECK-NEXT: [[NEGB:%.*]] = xor i32 [[B:%.*]], -1
+; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A:%.*]], [[NEGB]]
+; CHECK-NEXT: ret i32 [[XOR]]
+;
+ %nega = xor i32 %a, -1
+ %negb = xor i32 %b, -1
+ %and = and i32 %negb, %nega
+ %xor = xor i32 %a, %negb
+ %or = or i32 %and, %xor
+ ret i32 %or
+}
+
+; Commute operands of the 'or'.
+; (~A ^ B) | (~A & ~B) -> ~A ^ B
+
+define i32 @test46(i32 %a, i32 %b) {
+; CHECK-LABEL: @test46(
+; CHECK-NEXT: [[NEGB:%.*]] = xor i32 [[B:%.*]], -1
+; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A:%.*]], [[NEGB]]
+; CHECK-NEXT: ret i32 [[XOR]]
+;
+ %nega = xor i32 %a, -1
+ %negb = xor i32 %b, -1
+ %and = and i32 %nega, %negb
+ %xor = xor i32 %a, %negb
+ %or = or i32 %xor, %and
+ ret i32 %or
+}
+
+; (~A & ~B) | (~A ^ B) -> ~A ^ B
+
+define i32 @test46_commuted_and(i32 %a, i32 %b) {
+; CHECK-LABEL: @test46_commuted_and(
+; CHECK-NEXT: [[NEGB:%.*]] = xor i32 [[B:%.*]], -1
+; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A:%.*]], [[NEGB]]
+; CHECK-NEXT: ret i32 [[XOR]]
+;
+ %nega = xor i32 %a, -1
+ %negb = xor i32 %b, -1
+ %and = and i32 %negb, %nega
+ %xor = xor i32 %a, %negb
+ %or = or i32 %xor, %and
+ ret i32 %or
+}
diff --git a/test/Transforms/InstSimplify/icmp-ranges.ll b/test/Transforms/InstSimplify/icmp-ranges.ll
index dcbbe0bc7fb9..292be6a8a559 100644
--- a/test/Transforms/InstSimplify/icmp-ranges.ll
+++ b/test/Transforms/InstSimplify/icmp-ranges.ll
@@ -21,9 +21,7 @@ define i1 @and_eq_eq(i8 %x) {
define i1 @and_eq_ne(i8 %x) {
; CHECK-LABEL: @and_eq_ne(
; CHECK-NEXT: [[A:%.*]] = icmp eq i8 %x, 13
-; CHECK-NEXT: [[B:%.*]] = icmp ne i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[A]]
;
%a = icmp eq i8 %x, 13
%b = icmp ne i8 %x, 17
@@ -60,9 +58,7 @@ define i1 @and_eq_sgt(i8 %x) {
define i1 @and_eq_sle(i8 %x) {
; CHECK-LABEL: @and_eq_sle(
; CHECK-NEXT: [[A:%.*]] = icmp eq i8 %x, 13
-; CHECK-NEXT: [[B:%.*]] = icmp sle i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[A]]
;
%a = icmp eq i8 %x, 13
%b = icmp sle i8 %x, 17
@@ -75,9 +71,7 @@ define i1 @and_eq_sle(i8 %x) {
define i1 @and_eq_slt(i8 %x) {
; CHECK-LABEL: @and_eq_slt(
; CHECK-NEXT: [[A:%.*]] = icmp eq i8 %x, 13
-; CHECK-NEXT: [[B:%.*]] = icmp slt i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[A]]
;
%a = icmp eq i8 %x, 13
%b = icmp slt i8 %x, 17
@@ -114,9 +108,7 @@ define i1 @and_eq_ugt(i8 %x) {
define i1 @and_eq_ule(i8 %x) {
; CHECK-LABEL: @and_eq_ule(
; CHECK-NEXT: [[A:%.*]] = icmp eq i8 %x, 13
-; CHECK-NEXT: [[B:%.*]] = icmp ule i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[A]]
;
%a = icmp eq i8 %x, 13
%b = icmp ule i8 %x, 17
@@ -129,9 +121,7 @@ define i1 @and_eq_ule(i8 %x) {
define i1 @and_eq_ult(i8 %x) {
; CHECK-LABEL: @and_eq_ult(
; CHECK-NEXT: [[A:%.*]] = icmp eq i8 %x, 13
-; CHECK-NEXT: [[B:%.*]] = icmp ult i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[A]]
;
%a = icmp eq i8 %x, 13
%b = icmp ult i8 %x, 17
@@ -144,10 +134,8 @@ define i1 @and_eq_ult(i8 %x) {
define i1 @and_ne_eq(i8 %x) {
; CHECK-LABEL: @and_ne_eq(
-; CHECK-NEXT: [[A:%.*]] = icmp ne i8 %x, 13
; CHECK-NEXT: [[B:%.*]] = icmp eq i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[B]]
;
%a = icmp ne i8 %x, 13
%b = icmp eq i8 %x, 17
@@ -174,10 +162,8 @@ define i1 @and_ne_ne(i8 %x) {
define i1 @and_ne_sge(i8 %x) {
; CHECK-LABEL: @and_ne_sge(
-; CHECK-NEXT: [[A:%.*]] = icmp ne i8 %x, 13
; CHECK-NEXT: [[B:%.*]] = icmp sge i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[B]]
;
%a = icmp ne i8 %x, 13
%b = icmp sge i8 %x, 17
@@ -189,10 +175,8 @@ define i1 @and_ne_sge(i8 %x) {
define i1 @and_ne_sgt(i8 %x) {
; CHECK-LABEL: @and_ne_sgt(
-; CHECK-NEXT: [[A:%.*]] = icmp ne i8 %x, 13
; CHECK-NEXT: [[B:%.*]] = icmp sgt i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[B]]
;
%a = icmp ne i8 %x, 13
%b = icmp sgt i8 %x, 17
@@ -234,10 +218,8 @@ define i1 @and_ne_slt(i8 %x) {
define i1 @and_ne_uge(i8 %x) {
; CHECK-LABEL: @and_ne_uge(
-; CHECK-NEXT: [[A:%.*]] = icmp ne i8 %x, 13
; CHECK-NEXT: [[B:%.*]] = icmp uge i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[B]]
;
%a = icmp ne i8 %x, 13
%b = icmp uge i8 %x, 17
@@ -249,10 +231,8 @@ define i1 @and_ne_uge(i8 %x) {
define i1 @and_ne_ugt(i8 %x) {
; CHECK-LABEL: @and_ne_ugt(
-; CHECK-NEXT: [[A:%.*]] = icmp ne i8 %x, 13
; CHECK-NEXT: [[B:%.*]] = icmp ugt i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[B]]
;
%a = icmp ne i8 %x, 13
%b = icmp ugt i8 %x, 17
@@ -295,10 +275,8 @@ define i1 @and_ne_ult(i8 %x) {
define i1 @and_sge_eq(i8 %x) {
; CHECK-LABEL: @and_sge_eq(
-; CHECK-NEXT: [[A:%.*]] = icmp sge i8 %x, 13
; CHECK-NEXT: [[B:%.*]] = icmp eq i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[B]]
;
%a = icmp sge i8 %x, 13
%b = icmp eq i8 %x, 17
@@ -325,10 +303,8 @@ define i1 @and_sge_ne(i8 %x) {
define i1 @and_sge_sge(i8 %x) {
; CHECK-LABEL: @and_sge_sge(
-; CHECK-NEXT: [[A:%.*]] = icmp sge i8 %x, 13
; CHECK-NEXT: [[B:%.*]] = icmp sge i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[B]]
;
%a = icmp sge i8 %x, 13
%b = icmp sge i8 %x, 17
@@ -340,10 +316,8 @@ define i1 @and_sge_sge(i8 %x) {
define i1 @and_sge_sgt(i8 %x) {
; CHECK-LABEL: @and_sge_sgt(
-; CHECK-NEXT: [[A:%.*]] = icmp sge i8 %x, 13
; CHECK-NEXT: [[B:%.*]] = icmp sgt i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[B]]
;
%a = icmp sge i8 %x, 13
%b = icmp sgt i8 %x, 17
@@ -446,10 +420,8 @@ define i1 @and_sge_ult(i8 %x) {
define i1 @and_sgt_eq(i8 %x) {
; CHECK-LABEL: @and_sgt_eq(
-; CHECK-NEXT: [[A:%.*]] = icmp sgt i8 %x, 13
; CHECK-NEXT: [[B:%.*]] = icmp eq i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[B]]
;
%a = icmp sgt i8 %x, 13
%b = icmp eq i8 %x, 17
@@ -476,10 +448,8 @@ define i1 @and_sgt_ne(i8 %x) {
define i1 @and_sgt_sge(i8 %x) {
; CHECK-LABEL: @and_sgt_sge(
-; CHECK-NEXT: [[A:%.*]] = icmp sgt i8 %x, 13
; CHECK-NEXT: [[B:%.*]] = icmp sge i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[B]]
;
%a = icmp sgt i8 %x, 13
%b = icmp sge i8 %x, 17
@@ -491,10 +461,8 @@ define i1 @and_sgt_sge(i8 %x) {
define i1 @and_sgt_sgt(i8 %x) {
; CHECK-LABEL: @and_sgt_sgt(
-; CHECK-NEXT: [[A:%.*]] = icmp sgt i8 %x, 13
; CHECK-NEXT: [[B:%.*]] = icmp sgt i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[B]]
;
%a = icmp sgt i8 %x, 13
%b = icmp sgt i8 %x, 17
@@ -610,9 +578,7 @@ define i1 @and_sle_eq(i8 %x) {
define i1 @and_sle_ne(i8 %x) {
; CHECK-LABEL: @and_sle_ne(
; CHECK-NEXT: [[A:%.*]] = icmp sle i8 %x, 13
-; CHECK-NEXT: [[B:%.*]] = icmp ne i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[A]]
;
%a = icmp sle i8 %x, 13
%b = icmp ne i8 %x, 17
@@ -649,9 +615,7 @@ define i1 @and_sle_sgt(i8 %x) {
define i1 @and_sle_sle(i8 %x) {
; CHECK-LABEL: @and_sle_sle(
; CHECK-NEXT: [[A:%.*]] = icmp sle i8 %x, 13
-; CHECK-NEXT: [[B:%.*]] = icmp sle i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[A]]
;
%a = icmp sle i8 %x, 13
%b = icmp sle i8 %x, 17
@@ -664,9 +628,7 @@ define i1 @and_sle_sle(i8 %x) {
define i1 @and_sle_slt(i8 %x) {
; CHECK-LABEL: @and_sle_slt(
; CHECK-NEXT: [[A:%.*]] = icmp sle i8 %x, 13
-; CHECK-NEXT: [[B:%.*]] = icmp slt i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[A]]
;
%a = icmp sle i8 %x, 13
%b = icmp slt i8 %x, 17
@@ -752,9 +714,7 @@ define i1 @and_slt_eq(i8 %x) {
define i1 @and_slt_ne(i8 %x) {
; CHECK-LABEL: @and_slt_ne(
; CHECK-NEXT: [[A:%.*]] = icmp slt i8 %x, 13
-; CHECK-NEXT: [[B:%.*]] = icmp ne i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[A]]
;
%a = icmp slt i8 %x, 13
%b = icmp ne i8 %x, 17
@@ -791,9 +751,7 @@ define i1 @and_slt_sgt(i8 %x) {
define i1 @and_slt_sle(i8 %x) {
; CHECK-LABEL: @and_slt_sle(
; CHECK-NEXT: [[A:%.*]] = icmp slt i8 %x, 13
-; CHECK-NEXT: [[B:%.*]] = icmp sle i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[A]]
;
%a = icmp slt i8 %x, 13
%b = icmp sle i8 %x, 17
@@ -806,9 +764,7 @@ define i1 @and_slt_sle(i8 %x) {
define i1 @and_slt_slt(i8 %x) {
; CHECK-LABEL: @and_slt_slt(
; CHECK-NEXT: [[A:%.*]] = icmp slt i8 %x, 13
-; CHECK-NEXT: [[B:%.*]] = icmp slt i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[A]]
;
%a = icmp slt i8 %x, 13
%b = icmp slt i8 %x, 17
@@ -881,10 +837,8 @@ define i1 @and_slt_ult(i8 %x) {
define i1 @and_uge_eq(i8 %x) {
; CHECK-LABEL: @and_uge_eq(
-; CHECK-NEXT: [[A:%.*]] = icmp uge i8 %x, 13
; CHECK-NEXT: [[B:%.*]] = icmp eq i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[B]]
;
%a = icmp uge i8 %x, 13
%b = icmp eq i8 %x, 17
@@ -911,10 +865,8 @@ define i1 @and_uge_ne(i8 %x) {
define i1 @and_uge_sge(i8 %x) {
; CHECK-LABEL: @and_uge_sge(
-; CHECK-NEXT: [[A:%.*]] = icmp uge i8 %x, 13
; CHECK-NEXT: [[B:%.*]] = icmp sge i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[B]]
;
%a = icmp uge i8 %x, 13
%b = icmp sge i8 %x, 17
@@ -926,10 +878,8 @@ define i1 @and_uge_sge(i8 %x) {
define i1 @and_uge_sgt(i8 %x) {
; CHECK-LABEL: @and_uge_sgt(
-; CHECK-NEXT: [[A:%.*]] = icmp uge i8 %x, 13
; CHECK-NEXT: [[B:%.*]] = icmp sgt i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[B]]
;
%a = icmp uge i8 %x, 13
%b = icmp sgt i8 %x, 17
@@ -971,10 +921,8 @@ define i1 @and_uge_slt(i8 %x) {
define i1 @and_uge_uge(i8 %x) {
; CHECK-LABEL: @and_uge_uge(
-; CHECK-NEXT: [[A:%.*]] = icmp uge i8 %x, 13
; CHECK-NEXT: [[B:%.*]] = icmp uge i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[B]]
;
%a = icmp uge i8 %x, 13
%b = icmp uge i8 %x, 17
@@ -986,10 +934,8 @@ define i1 @and_uge_uge(i8 %x) {
define i1 @and_uge_ugt(i8 %x) {
; CHECK-LABEL: @and_uge_ugt(
-; CHECK-NEXT: [[A:%.*]] = icmp uge i8 %x, 13
; CHECK-NEXT: [[B:%.*]] = icmp ugt i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[B]]
;
%a = icmp uge i8 %x, 13
%b = icmp ugt i8 %x, 17
@@ -1032,10 +978,8 @@ define i1 @and_uge_ult(i8 %x) {
define i1 @and_ugt_eq(i8 %x) {
; CHECK-LABEL: @and_ugt_eq(
-; CHECK-NEXT: [[A:%.*]] = icmp ugt i8 %x, 13
; CHECK-NEXT: [[B:%.*]] = icmp eq i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[B]]
;
%a = icmp ugt i8 %x, 13
%b = icmp eq i8 %x, 17
@@ -1062,10 +1006,8 @@ define i1 @and_ugt_ne(i8 %x) {
define i1 @and_ugt_sge(i8 %x) {
; CHECK-LABEL: @and_ugt_sge(
-; CHECK-NEXT: [[A:%.*]] = icmp ugt i8 %x, 13
; CHECK-NEXT: [[B:%.*]] = icmp sge i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[B]]
;
%a = icmp ugt i8 %x, 13
%b = icmp sge i8 %x, 17
@@ -1077,10 +1019,8 @@ define i1 @and_ugt_sge(i8 %x) {
define i1 @and_ugt_sgt(i8 %x) {
; CHECK-LABEL: @and_ugt_sgt(
-; CHECK-NEXT: [[A:%.*]] = icmp ugt i8 %x, 13
; CHECK-NEXT: [[B:%.*]] = icmp sgt i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[B]]
;
%a = icmp ugt i8 %x, 13
%b = icmp sgt i8 %x, 17
@@ -1122,10 +1062,8 @@ define i1 @and_ugt_slt(i8 %x) {
define i1 @and_ugt_uge(i8 %x) {
; CHECK-LABEL: @and_ugt_uge(
-; CHECK-NEXT: [[A:%.*]] = icmp ugt i8 %x, 13
; CHECK-NEXT: [[B:%.*]] = icmp uge i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[B]]
;
%a = icmp ugt i8 %x, 13
%b = icmp uge i8 %x, 17
@@ -1137,10 +1075,8 @@ define i1 @and_ugt_uge(i8 %x) {
define i1 @and_ugt_ugt(i8 %x) {
; CHECK-LABEL: @and_ugt_ugt(
-; CHECK-NEXT: [[A:%.*]] = icmp ugt i8 %x, 13
; CHECK-NEXT: [[B:%.*]] = icmp ugt i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[B]]
;
%a = icmp ugt i8 %x, 13
%b = icmp ugt i8 %x, 17
@@ -1196,9 +1132,7 @@ define i1 @and_ule_eq(i8 %x) {
define i1 @and_ule_ne(i8 %x) {
; CHECK-LABEL: @and_ule_ne(
; CHECK-NEXT: [[A:%.*]] = icmp ule i8 %x, 13
-; CHECK-NEXT: [[B:%.*]] = icmp ne i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[A]]
;
%a = icmp ule i8 %x, 13
%b = icmp ne i8 %x, 17
@@ -1235,9 +1169,7 @@ define i1 @and_ule_sgt(i8 %x) {
define i1 @and_ule_sle(i8 %x) {
; CHECK-LABEL: @and_ule_sle(
; CHECK-NEXT: [[A:%.*]] = icmp ule i8 %x, 13
-; CHECK-NEXT: [[B:%.*]] = icmp sle i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[A]]
;
%a = icmp ule i8 %x, 13
%b = icmp sle i8 %x, 17
@@ -1250,9 +1182,7 @@ define i1 @and_ule_sle(i8 %x) {
define i1 @and_ule_slt(i8 %x) {
; CHECK-LABEL: @and_ule_slt(
; CHECK-NEXT: [[A:%.*]] = icmp ule i8 %x, 13
-; CHECK-NEXT: [[B:%.*]] = icmp slt i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[A]]
;
%a = icmp ule i8 %x, 13
%b = icmp slt i8 %x, 17
@@ -1289,9 +1219,7 @@ define i1 @and_ule_ugt(i8 %x) {
define i1 @and_ule_ule(i8 %x) {
; CHECK-LABEL: @and_ule_ule(
; CHECK-NEXT: [[A:%.*]] = icmp ule i8 %x, 13
-; CHECK-NEXT: [[B:%.*]] = icmp ule i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[A]]
;
%a = icmp ule i8 %x, 13
%b = icmp ule i8 %x, 17
@@ -1304,9 +1232,7 @@ define i1 @and_ule_ule(i8 %x) {
define i1 @and_ule_ult(i8 %x) {
; CHECK-LABEL: @and_ule_ult(
; CHECK-NEXT: [[A:%.*]] = icmp ule i8 %x, 13
-; CHECK-NEXT: [[B:%.*]] = icmp ult i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[A]]
;
%a = icmp ule i8 %x, 13
%b = icmp ult i8 %x, 17
@@ -1332,9 +1258,7 @@ define i1 @and_ult_eq(i8 %x) {
define i1 @and_ult_ne(i8 %x) {
; CHECK-LABEL: @and_ult_ne(
; CHECK-NEXT: [[A:%.*]] = icmp ult i8 %x, 13
-; CHECK-NEXT: [[B:%.*]] = icmp ne i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[A]]
;
%a = icmp ult i8 %x, 13
%b = icmp ne i8 %x, 17
@@ -1371,9 +1295,7 @@ define i1 @and_ult_sgt(i8 %x) {
define i1 @and_ult_sle(i8 %x) {
; CHECK-LABEL: @and_ult_sle(
; CHECK-NEXT: [[A:%.*]] = icmp ult i8 %x, 13
-; CHECK-NEXT: [[B:%.*]] = icmp sle i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[A]]
;
%a = icmp ult i8 %x, 13
%b = icmp sle i8 %x, 17
@@ -1386,9 +1308,7 @@ define i1 @and_ult_sle(i8 %x) {
define i1 @and_ult_slt(i8 %x) {
; CHECK-LABEL: @and_ult_slt(
; CHECK-NEXT: [[A:%.*]] = icmp ult i8 %x, 13
-; CHECK-NEXT: [[B:%.*]] = icmp slt i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[A]]
;
%a = icmp ult i8 %x, 13
%b = icmp slt i8 %x, 17
@@ -1425,9 +1345,7 @@ define i1 @and_ult_ugt(i8 %x) {
define i1 @and_ult_ule(i8 %x) {
; CHECK-LABEL: @and_ult_ule(
; CHECK-NEXT: [[A:%.*]] = icmp ult i8 %x, 13
-; CHECK-NEXT: [[B:%.*]] = icmp ule i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[A]]
;
%a = icmp ult i8 %x, 13
%b = icmp ule i8 %x, 17
@@ -1440,9 +1358,7 @@ define i1 @and_ult_ule(i8 %x) {
define i1 @and_ult_ult(i8 %x) {
; CHECK-LABEL: @and_ult_ult(
; CHECK-NEXT: [[A:%.*]] = icmp ult i8 %x, 13
-; CHECK-NEXT: [[B:%.*]] = icmp ult i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[A]]
;
%a = icmp ult i8 %x, 13
%b = icmp ult i8 %x, 17
@@ -1468,9 +1384,7 @@ define i1 @and_eq_eq_swap(i8 %x) {
define i1 @and_eq_ne_swap(i8 %x) {
; CHECK-LABEL: @and_eq_ne_swap(
; CHECK-NEXT: [[A:%.*]] = icmp eq i8 %x, 23
-; CHECK-NEXT: [[B:%.*]] = icmp ne i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[A]]
;
%a = icmp eq i8 %x, 23
%b = icmp ne i8 %x, 17
@@ -1483,9 +1397,7 @@ define i1 @and_eq_ne_swap(i8 %x) {
define i1 @and_eq_sge_swap(i8 %x) {
; CHECK-LABEL: @and_eq_sge_swap(
; CHECK-NEXT: [[A:%.*]] = icmp eq i8 %x, 23
-; CHECK-NEXT: [[B:%.*]] = icmp sge i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[A]]
;
%a = icmp eq i8 %x, 23
%b = icmp sge i8 %x, 17
@@ -1498,9 +1410,7 @@ define i1 @and_eq_sge_swap(i8 %x) {
define i1 @and_eq_sgt_swap(i8 %x) {
; CHECK-LABEL: @and_eq_sgt_swap(
; CHECK-NEXT: [[A:%.*]] = icmp eq i8 %x, 23
-; CHECK-NEXT: [[B:%.*]] = icmp sgt i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[A]]
;
%a = icmp eq i8 %x, 23
%b = icmp sgt i8 %x, 17
@@ -1537,9 +1447,7 @@ define i1 @and_eq_slt_swap(i8 %x) {
define i1 @and_eq_uge_swap(i8 %x) {
; CHECK-LABEL: @and_eq_uge_swap(
; CHECK-NEXT: [[A:%.*]] = icmp eq i8 %x, 23
-; CHECK-NEXT: [[B:%.*]] = icmp uge i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[A]]
;
%a = icmp eq i8 %x, 23
%b = icmp uge i8 %x, 17
@@ -1552,9 +1460,7 @@ define i1 @and_eq_uge_swap(i8 %x) {
define i1 @and_eq_ugt_swap(i8 %x) {
; CHECK-LABEL: @and_eq_ugt_swap(
; CHECK-NEXT: [[A:%.*]] = icmp eq i8 %x, 23
-; CHECK-NEXT: [[B:%.*]] = icmp ugt i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[A]]
;
%a = icmp eq i8 %x, 23
%b = icmp ugt i8 %x, 17
@@ -1591,10 +1497,8 @@ define i1 @and_eq_ult_swap(i8 %x) {
define i1 @and_ne_eq_swap(i8 %x) {
; CHECK-LABEL: @and_ne_eq_swap(
-; CHECK-NEXT: [[A:%.*]] = icmp ne i8 %x, 23
; CHECK-NEXT: [[B:%.*]] = icmp eq i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[B]]
;
%a = icmp ne i8 %x, 23
%b = icmp eq i8 %x, 17
@@ -1651,10 +1555,8 @@ define i1 @and_ne_sgt_swap(i8 %x) {
define i1 @and_ne_sle_swap(i8 %x) {
; CHECK-LABEL: @and_ne_sle_swap(
-; CHECK-NEXT: [[A:%.*]] = icmp ne i8 %x, 23
; CHECK-NEXT: [[B:%.*]] = icmp sle i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[B]]
;
%a = icmp ne i8 %x, 23
%b = icmp sle i8 %x, 17
@@ -1666,10 +1568,8 @@ define i1 @and_ne_sle_swap(i8 %x) {
define i1 @and_ne_slt_swap(i8 %x) {
; CHECK-LABEL: @and_ne_slt_swap(
-; CHECK-NEXT: [[A:%.*]] = icmp ne i8 %x, 23
; CHECK-NEXT: [[B:%.*]] = icmp slt i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[B]]
;
%a = icmp ne i8 %x, 23
%b = icmp slt i8 %x, 17
@@ -1711,10 +1611,8 @@ define i1 @and_ne_ugt_swap(i8 %x) {
define i1 @and_ne_ule_swap(i8 %x) {
; CHECK-LABEL: @and_ne_ule_swap(
-; CHECK-NEXT: [[A:%.*]] = icmp ne i8 %x, 23
; CHECK-NEXT: [[B:%.*]] = icmp ule i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[B]]
;
%a = icmp ne i8 %x, 23
%b = icmp ule i8 %x, 17
@@ -1726,10 +1624,8 @@ define i1 @and_ne_ule_swap(i8 %x) {
define i1 @and_ne_ult_swap(i8 %x) {
; CHECK-LABEL: @and_ne_ult_swap(
-; CHECK-NEXT: [[A:%.*]] = icmp ne i8 %x, 23
; CHECK-NEXT: [[B:%.*]] = icmp ult i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[B]]
;
%a = icmp ne i8 %x, 23
%b = icmp ult i8 %x, 17
@@ -1755,9 +1651,7 @@ define i1 @and_sge_eq_swap(i8 %x) {
define i1 @and_sge_ne_swap(i8 %x) {
; CHECK-LABEL: @and_sge_ne_swap(
; CHECK-NEXT: [[A:%.*]] = icmp sge i8 %x, 23
-; CHECK-NEXT: [[B:%.*]] = icmp ne i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[A]]
;
%a = icmp sge i8 %x, 23
%b = icmp ne i8 %x, 17
@@ -1770,9 +1664,7 @@ define i1 @and_sge_ne_swap(i8 %x) {
define i1 @and_sge_sge_swap(i8 %x) {
; CHECK-LABEL: @and_sge_sge_swap(
; CHECK-NEXT: [[A:%.*]] = icmp sge i8 %x, 23
-; CHECK-NEXT: [[B:%.*]] = icmp sge i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[A]]
;
%a = icmp sge i8 %x, 23
%b = icmp sge i8 %x, 17
@@ -1785,9 +1677,7 @@ define i1 @and_sge_sge_swap(i8 %x) {
define i1 @and_sge_sgt_swap(i8 %x) {
; CHECK-LABEL: @and_sge_sgt_swap(
; CHECK-NEXT: [[A:%.*]] = icmp sge i8 %x, 23
-; CHECK-NEXT: [[B:%.*]] = icmp sgt i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[A]]
;
%a = icmp sge i8 %x, 23
%b = icmp sgt i8 %x, 17
@@ -1824,9 +1714,7 @@ define i1 @and_sge_slt_swap(i8 %x) {
define i1 @and_sge_uge_swap(i8 %x) {
; CHECK-LABEL: @and_sge_uge_swap(
; CHECK-NEXT: [[A:%.*]] = icmp sge i8 %x, 23
-; CHECK-NEXT: [[B:%.*]] = icmp uge i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[A]]
;
%a = icmp sge i8 %x, 23
%b = icmp uge i8 %x, 17
@@ -1839,9 +1727,7 @@ define i1 @and_sge_uge_swap(i8 %x) {
define i1 @and_sge_ugt_swap(i8 %x) {
; CHECK-LABEL: @and_sge_ugt_swap(
; CHECK-NEXT: [[A:%.*]] = icmp sge i8 %x, 23
-; CHECK-NEXT: [[B:%.*]] = icmp ugt i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[A]]
;
%a = icmp sge i8 %x, 23
%b = icmp ugt i8 %x, 17
@@ -1891,9 +1777,7 @@ define i1 @and_sgt_eq_swap(i8 %x) {
define i1 @and_sgt_ne_swap(i8 %x) {
; CHECK-LABEL: @and_sgt_ne_swap(
; CHECK-NEXT: [[A:%.*]] = icmp sgt i8 %x, 23
-; CHECK-NEXT: [[B:%.*]] = icmp ne i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[A]]
;
%a = icmp sgt i8 %x, 23
%b = icmp ne i8 %x, 17
@@ -1906,9 +1790,7 @@ define i1 @and_sgt_ne_swap(i8 %x) {
define i1 @and_sgt_sge_swap(i8 %x) {
; CHECK-LABEL: @and_sgt_sge_swap(
; CHECK-NEXT: [[A:%.*]] = icmp sgt i8 %x, 23
-; CHECK-NEXT: [[B:%.*]] = icmp sge i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[A]]
;
%a = icmp sgt i8 %x, 23
%b = icmp sge i8 %x, 17
@@ -1921,9 +1803,7 @@ define i1 @and_sgt_sge_swap(i8 %x) {
define i1 @and_sgt_sgt_swap(i8 %x) {
; CHECK-LABEL: @and_sgt_sgt_swap(
; CHECK-NEXT: [[A:%.*]] = icmp sgt i8 %x, 23
-; CHECK-NEXT: [[B:%.*]] = icmp sgt i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[A]]
;
%a = icmp sgt i8 %x, 23
%b = icmp sgt i8 %x, 17
@@ -1960,9 +1840,7 @@ define i1 @and_sgt_slt_swap(i8 %x) {
define i1 @and_sgt_uge_swap(i8 %x) {
; CHECK-LABEL: @and_sgt_uge_swap(
; CHECK-NEXT: [[A:%.*]] = icmp sgt i8 %x, 23
-; CHECK-NEXT: [[B:%.*]] = icmp uge i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[A]]
;
%a = icmp sgt i8 %x, 23
%b = icmp uge i8 %x, 17
@@ -1975,9 +1853,7 @@ define i1 @and_sgt_uge_swap(i8 %x) {
define i1 @and_sgt_ugt_swap(i8 %x) {
; CHECK-LABEL: @and_sgt_ugt_swap(
; CHECK-NEXT: [[A:%.*]] = icmp sgt i8 %x, 23
-; CHECK-NEXT: [[B:%.*]] = icmp ugt i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[A]]
;
%a = icmp sgt i8 %x, 23
%b = icmp ugt i8 %x, 17
@@ -2014,10 +1890,8 @@ define i1 @and_sgt_ult_swap(i8 %x) {
define i1 @and_sle_eq_swap(i8 %x) {
; CHECK-LABEL: @and_sle_eq_swap(
-; CHECK-NEXT: [[A:%.*]] = icmp sle i8 %x, 23
; CHECK-NEXT: [[B:%.*]] = icmp eq i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[B]]
;
%a = icmp sle i8 %x, 23
%b = icmp eq i8 %x, 17
@@ -2074,10 +1948,8 @@ define i1 @and_sle_sgt_swap(i8 %x) {
define i1 @and_sle_sle_swap(i8 %x) {
; CHECK-LABEL: @and_sle_sle_swap(
-; CHECK-NEXT: [[A:%.*]] = icmp sle i8 %x, 23
; CHECK-NEXT: [[B:%.*]] = icmp sle i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[B]]
;
%a = icmp sle i8 %x, 23
%b = icmp sle i8 %x, 17
@@ -2089,10 +1961,8 @@ define i1 @and_sle_sle_swap(i8 %x) {
define i1 @and_sle_slt_swap(i8 %x) {
; CHECK-LABEL: @and_sle_slt_swap(
-; CHECK-NEXT: [[A:%.*]] = icmp sle i8 %x, 23
; CHECK-NEXT: [[B:%.*]] = icmp slt i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[B]]
;
%a = icmp sle i8 %x, 23
%b = icmp slt i8 %x, 17
@@ -2134,10 +2004,8 @@ define i1 @and_sle_ugt_swap(i8 %x) {
define i1 @and_sle_ule_swap(i8 %x) {
; CHECK-LABEL: @and_sle_ule_swap(
-; CHECK-NEXT: [[A:%.*]] = icmp sle i8 %x, 23
; CHECK-NEXT: [[B:%.*]] = icmp ule i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[B]]
;
%a = icmp sle i8 %x, 23
%b = icmp ule i8 %x, 17
@@ -2149,10 +2017,8 @@ define i1 @and_sle_ule_swap(i8 %x) {
define i1 @and_sle_ult_swap(i8 %x) {
; CHECK-LABEL: @and_sle_ult_swap(
-; CHECK-NEXT: [[A:%.*]] = icmp sle i8 %x, 23
; CHECK-NEXT: [[B:%.*]] = icmp ult i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[B]]
;
%a = icmp sle i8 %x, 23
%b = icmp ult i8 %x, 17
@@ -2165,10 +2031,8 @@ define i1 @and_sle_ult_swap(i8 %x) {
define i1 @and_slt_eq_swap(i8 %x) {
; CHECK-LABEL: @and_slt_eq_swap(
-; CHECK-NEXT: [[A:%.*]] = icmp slt i8 %x, 23
; CHECK-NEXT: [[B:%.*]] = icmp eq i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[B]]
;
%a = icmp slt i8 %x, 23
%b = icmp eq i8 %x, 17
@@ -2225,10 +2089,8 @@ define i1 @and_slt_sgt_swap(i8 %x) {
define i1 @and_slt_sle_swap(i8 %x) {
; CHECK-LABEL: @and_slt_sle_swap(
-; CHECK-NEXT: [[A:%.*]] = icmp slt i8 %x, 23
; CHECK-NEXT: [[B:%.*]] = icmp sle i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[B]]
;
%a = icmp slt i8 %x, 23
%b = icmp sle i8 %x, 17
@@ -2240,10 +2102,8 @@ define i1 @and_slt_sle_swap(i8 %x) {
define i1 @and_slt_slt_swap(i8 %x) {
; CHECK-LABEL: @and_slt_slt_swap(
-; CHECK-NEXT: [[A:%.*]] = icmp slt i8 %x, 23
; CHECK-NEXT: [[B:%.*]] = icmp slt i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[B]]
;
%a = icmp slt i8 %x, 23
%b = icmp slt i8 %x, 17
@@ -2285,10 +2145,8 @@ define i1 @and_slt_ugt_swap(i8 %x) {
define i1 @and_slt_ule_swap(i8 %x) {
; CHECK-LABEL: @and_slt_ule_swap(
-; CHECK-NEXT: [[A:%.*]] = icmp slt i8 %x, 23
; CHECK-NEXT: [[B:%.*]] = icmp ule i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[B]]
;
%a = icmp slt i8 %x, 23
%b = icmp ule i8 %x, 17
@@ -2300,10 +2158,8 @@ define i1 @and_slt_ule_swap(i8 %x) {
define i1 @and_slt_ult_swap(i8 %x) {
; CHECK-LABEL: @and_slt_ult_swap(
-; CHECK-NEXT: [[A:%.*]] = icmp slt i8 %x, 23
; CHECK-NEXT: [[B:%.*]] = icmp ult i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[B]]
;
%a = icmp slt i8 %x, 23
%b = icmp ult i8 %x, 17
@@ -2329,9 +2185,7 @@ define i1 @and_uge_eq_swap(i8 %x) {
define i1 @and_uge_ne_swap(i8 %x) {
; CHECK-LABEL: @and_uge_ne_swap(
; CHECK-NEXT: [[A:%.*]] = icmp uge i8 %x, 23
-; CHECK-NEXT: [[B:%.*]] = icmp ne i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[A]]
;
%a = icmp uge i8 %x, 23
%b = icmp ne i8 %x, 17
@@ -2404,9 +2258,7 @@ define i1 @and_uge_slt_swap(i8 %x) {
define i1 @and_uge_uge_swap(i8 %x) {
; CHECK-LABEL: @and_uge_uge_swap(
; CHECK-NEXT: [[A:%.*]] = icmp uge i8 %x, 23
-; CHECK-NEXT: [[B:%.*]] = icmp uge i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[A]]
;
%a = icmp uge i8 %x, 23
%b = icmp uge i8 %x, 17
@@ -2419,9 +2271,7 @@ define i1 @and_uge_uge_swap(i8 %x) {
define i1 @and_uge_ugt_swap(i8 %x) {
; CHECK-LABEL: @and_uge_ugt_swap(
; CHECK-NEXT: [[A:%.*]] = icmp uge i8 %x, 23
-; CHECK-NEXT: [[B:%.*]] = icmp ugt i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[A]]
;
%a = icmp uge i8 %x, 23
%b = icmp ugt i8 %x, 17
@@ -2471,9 +2321,7 @@ define i1 @and_ugt_eq_swap(i8 %x) {
define i1 @and_ugt_ne_swap(i8 %x) {
; CHECK-LABEL: @and_ugt_ne_swap(
; CHECK-NEXT: [[A:%.*]] = icmp ugt i8 %x, 23
-; CHECK-NEXT: [[B:%.*]] = icmp ne i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[A]]
;
%a = icmp ugt i8 %x, 23
%b = icmp ne i8 %x, 17
@@ -2546,9 +2394,7 @@ define i1 @and_ugt_slt_swap(i8 %x) {
define i1 @and_ugt_uge_swap(i8 %x) {
; CHECK-LABEL: @and_ugt_uge_swap(
; CHECK-NEXT: [[A:%.*]] = icmp ugt i8 %x, 23
-; CHECK-NEXT: [[B:%.*]] = icmp uge i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[A]]
;
%a = icmp ugt i8 %x, 23
%b = icmp uge i8 %x, 17
@@ -2561,9 +2407,7 @@ define i1 @and_ugt_uge_swap(i8 %x) {
define i1 @and_ugt_ugt_swap(i8 %x) {
; CHECK-LABEL: @and_ugt_ugt_swap(
; CHECK-NEXT: [[A:%.*]] = icmp ugt i8 %x, 23
-; CHECK-NEXT: [[B:%.*]] = icmp ugt i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[A]]
;
%a = icmp ugt i8 %x, 23
%b = icmp ugt i8 %x, 17
@@ -2600,10 +2444,8 @@ define i1 @and_ugt_ult_swap(i8 %x) {
define i1 @and_ule_eq_swap(i8 %x) {
; CHECK-LABEL: @and_ule_eq_swap(
-; CHECK-NEXT: [[A:%.*]] = icmp ule i8 %x, 23
; CHECK-NEXT: [[B:%.*]] = icmp eq i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[B]]
;
%a = icmp ule i8 %x, 23
%b = icmp eq i8 %x, 17
@@ -2720,10 +2562,8 @@ define i1 @and_ule_ugt_swap(i8 %x) {
define i1 @and_ule_ule_swap(i8 %x) {
; CHECK-LABEL: @and_ule_ule_swap(
-; CHECK-NEXT: [[A:%.*]] = icmp ule i8 %x, 23
; CHECK-NEXT: [[B:%.*]] = icmp ule i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[B]]
;
%a = icmp ule i8 %x, 23
%b = icmp ule i8 %x, 17
@@ -2735,10 +2575,8 @@ define i1 @and_ule_ule_swap(i8 %x) {
define i1 @and_ule_ult_swap(i8 %x) {
; CHECK-LABEL: @and_ule_ult_swap(
-; CHECK-NEXT: [[A:%.*]] = icmp ule i8 %x, 23
; CHECK-NEXT: [[B:%.*]] = icmp ult i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[B]]
;
%a = icmp ule i8 %x, 23
%b = icmp ult i8 %x, 17
@@ -2751,10 +2589,8 @@ define i1 @and_ule_ult_swap(i8 %x) {
define i1 @and_ult_eq_swap(i8 %x) {
; CHECK-LABEL: @and_ult_eq_swap(
-; CHECK-NEXT: [[A:%.*]] = icmp ult i8 %x, 23
; CHECK-NEXT: [[B:%.*]] = icmp eq i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[B]]
;
%a = icmp ult i8 %x, 23
%b = icmp eq i8 %x, 17
@@ -2871,10 +2707,8 @@ define i1 @and_ult_ugt_swap(i8 %x) {
define i1 @and_ult_ule_swap(i8 %x) {
; CHECK-LABEL: @and_ult_ule_swap(
-; CHECK-NEXT: [[A:%.*]] = icmp ult i8 %x, 23
; CHECK-NEXT: [[B:%.*]] = icmp ule i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[B]]
;
%a = icmp ult i8 %x, 23
%b = icmp ule i8 %x, 17
@@ -2886,10 +2720,8 @@ define i1 @and_ult_ule_swap(i8 %x) {
define i1 @and_ult_ult_swap(i8 %x) {
; CHECK-LABEL: @and_ult_ult_swap(
-; CHECK-NEXT: [[A:%.*]] = icmp ult i8 %x, 23
; CHECK-NEXT: [[B:%.*]] = icmp ult i8 %x, 17
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 [[B]]
;
%a = icmp ult i8 %x, 23
%b = icmp ult i8 %x, 17
diff --git a/test/Transforms/JumpThreading/fold-not-thread.ll b/test/Transforms/JumpThreading/fold-not-thread.ll
new file mode 100644
index 000000000000..75deca62f753
--- /dev/null
+++ b/test/Transforms/JumpThreading/fold-not-thread.ll
@@ -0,0 +1,135 @@
+; RUN: opt -jump-threading -S -verify < %s | FileCheck %s
+
+declare i32 @f1()
+declare i32 @f2()
+declare void @f3()
+declare void @f4(i32)
+
+
+; Make sure we update the phi node properly.
+;
+; CHECK-LABEL: define void @test_br_folding_not_threading_update_phi(
+; CHECK: br label %L1
+; Make sure we update the phi node properly here, i.e. we only have 2 predecessors, entry and L0
+; CHECK: %res.0 = phi i32 [ 0, %L0 ], [ 1, %entry ]
+define void @test_br_folding_not_threading_update_phi(i32 %val) nounwind {
+entry:
+ %cmp = icmp eq i32 %val, 32
+ br i1 %cmp, label %L0, label %L1
+L0:
+ call i32 @f2()
+ call i32 @f2()
+ call i32 @f2()
+ call i32 @f2()
+ call i32 @f2()
+ call i32 @f2()
+ call i32 @f2()
+ call i32 @f2()
+ call i32 @f2()
+ call i32 @f2()
+ call i32 @f2()
+ call i32 @f2()
+ call i32 @f2()
+ switch i32 %val, label %L2 [
+ i32 0, label %L1
+ i32 32, label %L1
+ ]
+
+L1:
+ %res.0 = phi i32 [ 0, %L0 ], [ 0, %L0 ], [1, %entry]
+ call void @f4(i32 %res.0)
+ ret void
+L2:
+ call void @f3()
+ ret void
+}
+
+; Make sure we can fold this branch ... We will not be able to thread it as
+; L0 is too big to duplicate. L2 is the unreachable block here.
+;
+; CHECK-LABEL: @test_br_folding_not_threading(
+; CHECK: L1:
+; CHECK: call i32 @f2()
+; CHECK: call void @f3()
+; CHECK-NEXT: ret void
+; CHECK-NOT: br
+; CHECK: L3:
+define void @test_br_folding_not_threading(i1 %cond) nounwind {
+entry:
+ br i1 %cond, label %L0, label %L3
+L0:
+ call i32 @f2()
+ call i32 @f2()
+ call i32 @f2()
+ call i32 @f2()
+ call i32 @f2()
+ call i32 @f2()
+ call i32 @f2()
+ call i32 @f2()
+ call i32 @f2()
+ call i32 @f2()
+ call i32 @f2()
+ call i32 @f2()
+ call i32 @f2()
+ br i1 %cond, label %L1, label %L2
+
+L1:
+ call void @f3()
+ ret void
+L2:
+ call void @f3()
+ ret void
+L3:
+ call void @f3()
+ ret void
+}
+
+
+; Make sure we can fold this branch ... We will not be able to thread it as
+; L0 is too big to duplicate. L2 is the unreachable block here.
+; With more than 1 predecessors.
+;
+; CHECK-LABEL: @test_br_folding_not_threading_multiple_preds(
+; CHECK: L1:
+; CHECK: call i32 @f2()
+; CHECK: call void @f3()
+; CHECK-NEXT: ret void
+; CHECK-NOT: br
+; CHECK: L3:
+define void @test_br_folding_not_threading_multiple_preds(i1 %condx, i1 %cond) nounwind {
+entry:
+ br i1 %condx, label %X0, label %X1
+
+X0:
+ br i1 %cond, label %L0, label %L3
+
+X1:
+ br i1 %cond, label %L0, label %L3
+
+L0:
+ call i32 @f2()
+ call i32 @f2()
+ call i32 @f2()
+ call i32 @f2()
+ call i32 @f2()
+ call i32 @f2()
+ call i32 @f2()
+ call i32 @f2()
+ call i32 @f2()
+ call i32 @f2()
+ call i32 @f2()
+ call i32 @f2()
+ call i32 @f2()
+ br i1 %cond, label %L1, label %L2
+
+L1:
+ call void @f3()
+ ret void
+L2:
+ call void @f3()
+ ret void
+L3:
+ call void @f3()
+ ret void
+}
+
diff --git a/test/Transforms/LoadStoreVectorizer/AMDGPU/gep-bitcast.ll b/test/Transforms/LoadStoreVectorizer/AMDGPU/gep-bitcast.ll
new file mode 100644
index 000000000000..b67dc0584537
--- /dev/null
+++ b/test/Transforms/LoadStoreVectorizer/AMDGPU/gep-bitcast.ll
@@ -0,0 +1,83 @@
+; RUN: opt -S -mtriple=amdgcn--amdhsa -load-store-vectorizer < %s | FileCheck %s
+
+; Check that vectorizer can find a GEP through bitcast
+; CHECK-LABEL: @vect_zext_bitcast_f32_to_i32_idx
+; CHECK: load <4 x i32>
+define void @vect_zext_bitcast_f32_to_i32_idx(float addrspace(1)* %arg1, i32 %base) {
+ %add1 = add nuw i32 %base, 0
+ %zext1 = zext i32 %add1 to i64
+ %gep1 = getelementptr inbounds float, float addrspace(1)* %arg1, i64 %zext1
+ %f2i1 = bitcast float addrspace(1)* %gep1 to i32 addrspace(1)*
+ %load1 = load i32, i32 addrspace(1)* %f2i1, align 4
+ %add2 = add nuw i32 %base, 1
+ %zext2 = zext i32 %add2 to i64
+ %gep2 = getelementptr inbounds float, float addrspace(1)* %arg1, i64 %zext2
+ %f2i2 = bitcast float addrspace(1)* %gep2 to i32 addrspace(1)*
+ %load2 = load i32, i32 addrspace(1)* %f2i2, align 4
+ %add3 = add nuw i32 %base, 2
+ %zext3 = zext i32 %add3 to i64
+ %gep3 = getelementptr inbounds float, float addrspace(1)* %arg1, i64 %zext3
+ %f2i3 = bitcast float addrspace(1)* %gep3 to i32 addrspace(1)*
+ %load3 = load i32, i32 addrspace(1)* %f2i3, align 4
+ %add4 = add nuw i32 %base, 3
+ %zext4 = zext i32 %add4 to i64
+ %gep4 = getelementptr inbounds float, float addrspace(1)* %arg1, i64 %zext4
+ %f2i4 = bitcast float addrspace(1)* %gep4 to i32 addrspace(1)*
+ %load4 = load i32, i32 addrspace(1)* %f2i4, align 4
+ ret void
+}
+
+; CHECK-LABEL: @vect_zext_bitcast_i8_st1_to_i32_idx
+; CHECK: load i32
+; CHECK: load i32
+; CHECK: load i32
+; CHECK: load i32
+define void @vect_zext_bitcast_i8_st1_to_i32_idx(i8 addrspace(1)* %arg1, i32 %base) {
+ %add1 = add nuw i32 %base, 0
+ %zext1 = zext i32 %add1 to i64
+ %gep1 = getelementptr inbounds i8, i8 addrspace(1)* %arg1, i64 %zext1
+ %f2i1 = bitcast i8 addrspace(1)* %gep1 to i32 addrspace(1)*
+ %load1 = load i32, i32 addrspace(1)* %f2i1, align 4
+ %add2 = add nuw i32 %base, 1
+ %zext2 = zext i32 %add2 to i64
+ %gep2 = getelementptr inbounds i8,i8 addrspace(1)* %arg1, i64 %zext2
+ %f2i2 = bitcast i8 addrspace(1)* %gep2 to i32 addrspace(1)*
+ %load2 = load i32, i32 addrspace(1)* %f2i2, align 4
+ %add3 = add nuw i32 %base, 2
+ %zext3 = zext i32 %add3 to i64
+ %gep3 = getelementptr inbounds i8, i8 addrspace(1)* %arg1, i64 %zext3
+ %f2i3 = bitcast i8 addrspace(1)* %gep3 to i32 addrspace(1)*
+ %load3 = load i32, i32 addrspace(1)* %f2i3, align 4
+ %add4 = add nuw i32 %base, 3
+ %zext4 = zext i32 %add4 to i64
+ %gep4 = getelementptr inbounds i8, i8 addrspace(1)* %arg1, i64 %zext4
+ %f2i4 = bitcast i8 addrspace(1)* %gep4 to i32 addrspace(1)*
+ %load4 = load i32, i32 addrspace(1)* %f2i4, align 4
+ ret void
+}
+
+; TODO: This can be vectorized, but currently vectorizer unable to do it.
+; CHECK-LABEL: @vect_zext_bitcast_i8_st4_to_i32_idx
+define void @vect_zext_bitcast_i8_st4_to_i32_idx(i8 addrspace(1)* %arg1, i32 %base) {
+ %add1 = add nuw i32 %base, 0
+ %zext1 = zext i32 %add1 to i64
+ %gep1 = getelementptr inbounds i8, i8 addrspace(1)* %arg1, i64 %zext1
+ %f2i1 = bitcast i8 addrspace(1)* %gep1 to i32 addrspace(1)*
+ %load1 = load i32, i32 addrspace(1)* %f2i1, align 4
+ %add2 = add nuw i32 %base, 4
+ %zext2 = zext i32 %add2 to i64
+ %gep2 = getelementptr inbounds i8,i8 addrspace(1)* %arg1, i64 %zext2
+ %f2i2 = bitcast i8 addrspace(1)* %gep2 to i32 addrspace(1)*
+ %load2 = load i32, i32 addrspace(1)* %f2i2, align 4
+ %add3 = add nuw i32 %base, 8
+ %zext3 = zext i32 %add3 to i64
+ %gep3 = getelementptr inbounds i8, i8 addrspace(1)* %arg1, i64 %zext3
+ %f2i3 = bitcast i8 addrspace(1)* %gep3 to i32 addrspace(1)*
+ %load3 = load i32, i32 addrspace(1)* %f2i3, align 4
+ %add4 = add nuw i32 %base, 16
+ %zext4 = zext i32 %add4 to i64
+ %gep4 = getelementptr inbounds i8, i8 addrspace(1)* %arg1, i64 %zext4
+ %f2i4 = bitcast i8 addrspace(1)* %gep4 to i32 addrspace(1)*
+ %load4 = load i32, i32 addrspace(1)* %f2i4, align 4
+ ret void
+}
diff --git a/test/Transforms/LoopIdiom/non-integral-pointers.ll b/test/Transforms/LoopIdiom/non-integral-pointers.ll
new file mode 100644
index 000000000000..7646d5ac72d1
--- /dev/null
+++ b/test/Transforms/LoopIdiom/non-integral-pointers.ll
@@ -0,0 +1,48 @@
+; RUN: opt -S -basicaa -loop-idiom < %s | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128-ni:4"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @f_0(i8 addrspace(3)** %ptr) {
+; CHECK-LABEL: @f_0(
+; CHECK: call{{.*}}memset
+
+; LIR'ing stores of pointers with address space 3 is fine, since
+; they're integral pointers.
+
+entry:
+ br label %for.body
+
+for.body:
+ %indvar = phi i64 [ 0, %entry ], [ %indvar.next, %for.body ]
+ %arrayidx = getelementptr i8 addrspace(3)*, i8 addrspace(3)** %ptr, i64 %indvar
+ store i8 addrspace(3)* null, i8 addrspace(3)** %arrayidx, align 4
+ %indvar.next = add i64 %indvar, 1
+ %exitcond = icmp eq i64 %indvar.next, 10000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+define void @f_1(i8 addrspace(4)** %ptr) {
+; CHECK-LABEL: @f_1(
+; CHECK-NOT: call{{.*}}memset
+
+; LIR'ing stores of pointers with address space 4 is not ok, since
+; they're non-integral pointers.
+
+entry:
+ br label %for.body
+
+for.body:
+ %indvar = phi i64 [ 0, %entry ], [ %indvar.next, %for.body ]
+ %arrayidx = getelementptr i8 addrspace(4)*, i8 addrspace(4)** %ptr, i64 %indvar
+ store i8 addrspace(4)* null, i8 addrspace(4)** %arrayidx, align 4
+ %indvar.next = add i64 %indvar, 1
+ %exitcond = icmp eq i64 %indvar.next, 10000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
diff --git a/test/Transforms/LoopUnroll/not-rotated.ll b/test/Transforms/LoopUnroll/not-rotated.ll
new file mode 100644
index 000000000000..ffe80920d948
--- /dev/null
+++ b/test/Transforms/LoopUnroll/not-rotated.ll
@@ -0,0 +1,26 @@
+; PR28103
+; Bail out if the two successors are not the header
+; and another bb outside of the loop. This case is not
+; properly handled by LoopUnroll, currently.
+
+; RUN: opt -loop-unroll -verify-dom-info %s
+; REQUIRE: asserts
+
+define void @tinkywinky(i1 %patatino) {
+entry:
+ br label %header1
+header1:
+ %indvars.iv = phi i64 [ 1, %body2 ], [ 0, %entry ]
+ %exitcond = icmp ne i64 %indvars.iv, 1
+ br i1 %exitcond, label %body1, label %exit
+body1:
+ br i1 %patatino, label %body2, label %sink
+body2:
+ br i1 %patatino, label %header1, label %body3
+body3:
+ br label %sink
+sink:
+ br label %body2
+exit:
+ ret void
+}
diff --git a/test/Transforms/LoopVectorize/X86/float-induction-x86.ll b/test/Transforms/LoopVectorize/X86/float-induction-x86.ll
index 08ac64e52d4f..b5e914500fb4 100644
--- a/test/Transforms/LoopVectorize/X86/float-induction-x86.ll
+++ b/test/Transforms/LoopVectorize/X86/float-induction-x86.ll
@@ -82,5 +82,68 @@ for.end: ; preds = %for.end.loopexit, %
ret void
}
+; AUTO_VEC-LABEL: @external_use_with_fast_math(
+; AUTO_VEC-NEXT: entry:
+; AUTO_VEC-NEXT: [[TMP0:%.*]] = icmp sgt i64 %n, 1
+; AUTO_VEC-NEXT: [[SMAX:%.*]] = select i1 [[TMP0]], i64 %n, i64 1
+; AUTO_VEC: br i1 {{.*}}, label %for.body, label %min.iters.checked
+; AUTO_VEC: min.iters.checked:
+; AUTO_VEC-NEXT: [[N_VEC:%.*]] = and i64 [[SMAX]], 9223372036854775792
+; AUTO_VEC: br i1 {{.*}}, label %for.body, label %vector.body
+; AUTO_VEC: middle.block:
+; AUTO_VEC: [[TMP11:%.*]] = add nsw i64 [[N_VEC]], -1
+; AUTO_VEC-NEXT: [[CAST_CMO:%.*]] = sitofp i64 [[TMP11]] to double
+; AUTO_VEC-NEXT: [[TMP12:%.*]] = fmul fast double [[CAST_CMO]], 3.000000e+00
+; AUTO_VEC-NEXT: br i1 {{.*}}, label %for.end, label %for.body
+; AUTO_VEC: for.end:
+; AUTO_VEC-NEXT: [[J_LCSSA:%.*]] = phi double [ [[TMP12]], %middle.block ], [ %j, %for.body ]
+; AUTO_VEC-NEXT: ret double [[J_LCSSA]]
+;
+define double @external_use_with_fast_math(double* %a, i64 %n) {
+entry:
+ br label %for.body
+
+for.body:
+ %i = phi i64 [ 0, %entry ], [%i.next, %for.body]
+ %j = phi double [ 0.0, %entry ], [ %j.next, %for.body ]
+ %tmp0 = getelementptr double, double* %a, i64 %i
+ store double %j, double* %tmp0
+ %i.next = add i64 %i, 1
+ %j.next = fadd fast double %j, 3.0
+ %cond = icmp slt i64 %i.next, %n
+ br i1 %cond, label %for.body, label %for.end
+
+for.end:
+ %tmp1 = phi double [ %j, %for.body ]
+ ret double %tmp1
+}
+
+; AUTO_VEC-LABEL: @external_use_without_fast_math(
+; AUTO_VEC: for.body:
+; AUTO_VEC: [[J:%.*]] = phi double [ 0.000000e+00, %entry ], [ [[J_NEXT:%.*]], %for.body ]
+; AUTO_VEC: [[J_NEXT]] = fadd double [[J]], 3.000000e+00
+; AUTO_VEC: br i1 {{.*}}, label %for.body, label %for.end
+; AUTO_VEC: for.end:
+; AUTO_VEC-NEXT: ret double [[J]]
+;
+define double @external_use_without_fast_math(double* %a, i64 %n) {
+entry:
+ br label %for.body
+
+for.body:
+ %i = phi i64 [ 0, %entry ], [%i.next, %for.body]
+ %j = phi double [ 0.0, %entry ], [ %j.next, %for.body ]
+ %tmp0 = getelementptr double, double* %a, i64 %i
+ store double %j, double* %tmp0
+ %i.next = add i64 %i, 1
+ %j.next = fadd double %j, 3.0
+ %cond = icmp slt i64 %i.next, %n
+ br i1 %cond, label %for.body, label %for.end
+
+for.end:
+ %tmp1 = phi double [ %j, %for.body ]
+ ret double %tmp1
+}
+
attributes #0 = { "no-nans-fp-math"="true" }
attributes #1 = { "no-nans-fp-math"="false" }
diff --git a/test/Transforms/LoopVectorize/induction.ll b/test/Transforms/LoopVectorize/induction.ll
index 0d7d9fe0c1b8..6507166dd1f2 100644
--- a/test/Transforms/LoopVectorize/induction.ll
+++ b/test/Transforms/LoopVectorize/induction.ll
@@ -309,59 +309,59 @@ for.end:
;
; CHECK-LABEL: @scalarize_induction_variable_05(
; CHECK: vector.body:
-; CHECK: %index = phi i32 [ 0, %vector.ph ], [ %index.next, %pred.udiv.continue2 ]
+; CHECK: %index = phi i32 [ 0, %vector.ph ], [ %index.next, %pred.udiv.continue{{[0-9]+}} ]
; CHECK: %[[I0:.+]] = add i32 %index, 0
; CHECK: getelementptr inbounds i32, i32* %a, i32 %[[I0]]
; CHECK: pred.udiv.if:
; CHECK: udiv i32 {{.*}}, %[[I0]]
-; CHECK: pred.udiv.if1:
+; CHECK: pred.udiv.if{{[0-9]+}}:
; CHECK: %[[I1:.+]] = add i32 %index, 1
; CHECK: udiv i32 {{.*}}, %[[I1]]
;
; UNROLL-NO_IC-LABEL: @scalarize_induction_variable_05(
; UNROLL-NO-IC: vector.body:
-; UNROLL-NO-IC: %index = phi i32 [ 0, %vector.ph ], [ %index.next, %pred.udiv.continue11 ]
+; UNROLL-NO-IC: %index = phi i32 [ 0, %vector.ph ], [ %index.next, %pred.udiv.continue{{[0-9]+}} ]
; UNROLL-NO-IC: %[[I0:.+]] = add i32 %index, 0
; UNROLL-NO-IC: %[[I2:.+]] = add i32 %index, 2
; UNROLL-NO-IC: getelementptr inbounds i32, i32* %a, i32 %[[I0]]
; UNROLL-NO-IC: getelementptr inbounds i32, i32* %a, i32 %[[I2]]
; UNROLL-NO-IC: pred.udiv.if:
; UNROLL-NO-IC: udiv i32 {{.*}}, %[[I0]]
-; UNROLL-NO-IC: pred.udiv.if6:
+; UNROLL-NO-IC: pred.udiv.if{{[0-9]+}}:
; UNROLL-NO-IC: %[[I1:.+]] = add i32 %index, 1
; UNROLL-NO-IC: udiv i32 {{.*}}, %[[I1]]
-; UNROLL-NO-IC: pred.udiv.if8:
+; UNROLL-NO-IC: pred.udiv.if{{[0-9]+}}:
; UNROLL-NO-IC: udiv i32 {{.*}}, %[[I2]]
-; UNROLL-NO-IC: pred.udiv.if10:
+; UNROLL-NO-IC: pred.udiv.if{{[0-9]+}}:
; UNROLL-NO-IC: %[[I3:.+]] = add i32 %index, 3
; UNROLL-NO-IC: udiv i32 {{.*}}, %[[I3]]
;
; IND-LABEL: @scalarize_induction_variable_05(
; IND: vector.body:
-; IND: %index = phi i32 [ 0, %vector.ph ], [ %index.next, %pred.udiv.continue2 ]
+; IND: %index = phi i32 [ 0, %vector.ph ], [ %index.next, %pred.udiv.continue{{[0-9]+}} ]
; IND: %[[E0:.+]] = sext i32 %index to i64
; IND: getelementptr inbounds i32, i32* %a, i64 %[[E0]]
; IND: pred.udiv.if:
; IND: udiv i32 {{.*}}, %index
-; IND: pred.udiv.if1:
+; IND: pred.udiv.if{{[0-9]+}}:
; IND: %[[I1:.+]] = or i32 %index, 1
; IND: udiv i32 {{.*}}, %[[I1]]
;
; UNROLL-LABEL: @scalarize_induction_variable_05(
; UNROLL: vector.body:
-; UNROLL: %index = phi i32 [ 0, %vector.ph ], [ %index.next, %pred.udiv.continue11 ]
+; UNROLL: %index = phi i32 [ 0, %vector.ph ], [ %index.next, %pred.udiv.continue{{[0-9]+}} ]
; UNROLL: %[[I2:.+]] = or i32 %index, 2
; UNROLL: %[[E0:.+]] = sext i32 %index to i64
; UNROLL: %[[G0:.+]] = getelementptr inbounds i32, i32* %a, i64 %[[E0]]
; UNROLL: getelementptr i32, i32* %[[G0]], i64 2
; UNROLL: pred.udiv.if:
; UNROLL: udiv i32 {{.*}}, %index
-; UNROLL: pred.udiv.if6:
+; UNROLL: pred.udiv.if{{[0-9]+}}:
; UNROLL: %[[I1:.+]] = or i32 %index, 1
; UNROLL: udiv i32 {{.*}}, %[[I1]]
-; UNROLL: pred.udiv.if8:
+; UNROLL: pred.udiv.if{{[0-9]+}}:
; UNROLL: udiv i32 {{.*}}, %[[I2]]
-; UNROLL: pred.udiv.if10:
+; UNROLL: pred.udiv.if{{[0-9]+}}:
; UNROLL: %[[I3:.+]] = or i32 %index, 3
; UNROLL: udiv i32 {{.*}}, %[[I3]]
diff --git a/test/Transforms/LoopVectorize/phi-cost.ll b/test/Transforms/LoopVectorize/phi-cost.ll
new file mode 100644
index 000000000000..5ccea66c76af
--- /dev/null
+++ b/test/Transforms/LoopVectorize/phi-cost.ll
@@ -0,0 +1,86 @@
+; REQUIRES: asserts
+; RUN: opt < %s -loop-vectorize -force-vector-width=2 -force-vector-interleave=1 -instcombine -debug-only=loop-vectorize -disable-output -print-after=instcombine 2>&1 | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-i128:128-n32:64-S128"
+
+; CHECK-LABEL: phi_two_incoming_values
+; CHECK: LV: Found an estimated cost of 1 for VF 2 For instruction: %i = phi i64 [ %i.next, %if.end ], [ 0, %entry ]
+; CHECK: LV: Found an estimated cost of 1 for VF 2 For instruction: %tmp5 = phi i32 [ %tmp1, %for.body ], [ %tmp4, %if.then ]
+; CHECK: vector.body:
+; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %vector.ph ], [ [[INDEX_NEXT:%.*]], %vector.body ]
+; CHECK: [[WIDE_LOAD:%.*]] = load <2 x i32>, <2 x i32>* {{.*}}
+; CHECK: [[TMP5:%.*]] = icmp sgt <2 x i32> [[WIDE_LOAD]], zeroinitializer
+; CHECK-NEXT: [[TMP6:%.*]] = add <2 x i32> [[WIDE_LOAD]], <i32 1, i32 1>
+; CHECK-NEXT: [[PREDPHI:%.*]] = select <2 x i1> [[TMP5]], <2 x i32> [[TMP6]], <2 x i32> [[WIDE_LOAD]]
+; CHECK: store <2 x i32> [[PREDPHI]], <2 x i32>* {{.*}}
+; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 2
+;
+define void @phi_two_incoming_values(i32* %a, i32* %b, i64 %n) {
+entry:
+ br label %for.body
+
+for.body:
+ %i = phi i64 [ %i.next, %if.end ], [ 0, %entry ]
+ %tmp0 = getelementptr inbounds i32, i32* %a, i64 %i
+ %tmp1 = load i32, i32* %tmp0, align 4
+ %tmp2 = getelementptr inbounds i32, i32* %b, i64 %i
+ %tmp3 = icmp sgt i32 %tmp1, 0
+ br i1 %tmp3, label %if.then, label %if.end
+
+if.then:
+ %tmp4 = add i32 %tmp1, 1
+ br label %if.end
+
+if.end:
+ %tmp5 = phi i32 [ %tmp1, %for.body ], [ %tmp4, %if.then ]
+ store i32 %tmp5, i32* %tmp2, align 4
+ %i.next = add i64 %i, 1
+ %cond = icmp eq i64 %i, %n
+ br i1 %cond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+; CHECK-LABEL: phi_three_incoming_values
+; CHECK: LV: Found an estimated cost of 1 for VF 2 For instruction: %i = phi i64 [ %i.next, %if.end ], [ 0, %entry ]
+; CHECK: LV: Found an estimated cost of 2 for VF 2 For instruction: %tmp8 = phi i32 [ 9, %for.body ], [ 3, %if.then ], [ %tmp7, %if.else ]
+; CHECK: vector.body:
+; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %vector.ph ], [ [[INDEX_NEXT:%.*]], %vector.body ]
+; CHECK: [[PREDPHI:%.*]] = select <2 x i1> {{.*}}, <2 x i32> <i32 3, i32 3>, <2 x i32> <i32 9, i32 9>
+; CHECK: [[PREDPHI7:%.*]] = select <2 x i1> {{.*}}, <2 x i32> {{.*}}, <2 x i32> [[PREDPHI]]
+; CHECK: store <2 x i32> [[PREDPHI7]], <2 x i32>* {{.*}}
+; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 2
+;
+define void @phi_three_incoming_values(i32* %a, i32* %b, i64 %n) {
+entry:
+ br label %for.body
+
+for.body:
+ %i = phi i64 [ %i.next, %if.end ], [ 0, %entry ]
+ %tmp0 = getelementptr inbounds i32, i32* %a, i64 %i
+ %tmp1 = load i32, i32* %tmp0, align 4
+ %tmp2 = getelementptr inbounds i32, i32* %b, i64 %i
+ %tmp3 = load i32, i32* %tmp2, align 4
+ %tmp4 = icmp sgt i32 %tmp1, %tmp3
+ br i1 %tmp4, label %if.then, label %if.end
+
+if.then:
+ %tmp5 = icmp sgt i32 %tmp1, 19
+ br i1 %tmp5, label %if.end, label %if.else
+
+if.else:
+ %tmp6 = icmp slt i32 %tmp3, 4
+ %tmp7 = select i1 %tmp6, i32 4, i32 5
+ br label %if.end
+
+if.end:
+ %tmp8 = phi i32 [ 9, %for.body ], [ 3, %if.then ], [ %tmp7, %if.else ]
+ store i32 %tmp8, i32* %tmp0, align 4
+ %i.next = add i64 %i, 1
+ %cond = icmp eq i64 %i, %n
+ br i1 %cond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
diff --git a/test/Transforms/LowerSwitch/phi-in-dead-block.ll b/test/Transforms/LowerSwitch/phi-in-dead-block.ll
new file mode 100644
index 000000000000..a632584f7eb9
--- /dev/null
+++ b/test/Transforms/LowerSwitch/phi-in-dead-block.ll
@@ -0,0 +1,40 @@
+; RUN: opt -S -lowerswitch %s | FileCheck %s
+
+; CHECK-LABEL: @phi_in_dead_block(
+; CHECK-NOT: switch
+define void @phi_in_dead_block() {
+bb:
+ br i1 undef, label %bb2, label %bb3
+
+bb1: ; No predecessors!
+ switch i32 undef, label %bb2 [
+ i32 9, label %bb3
+ ]
+
+bb2: ; preds = %bb1, %bb
+ %tmp = phi i64 [ undef, %bb1 ], [ undef, %bb ]
+ unreachable
+
+bb3: ; preds = %bb1, %bb
+ unreachable
+}
+
+; CHECK-LABEL: @phi_in_dead_block_br_to_self(
+; CHECK-NOT: switch
+define void @phi_in_dead_block_br_to_self() {
+bb:
+ br i1 undef, label %bb2, label %bb3
+
+bb1: ; No predecessors!
+ switch i32 undef, label %bb2 [
+ i32 9, label %bb3
+ i32 10, label %bb1
+ ]
+
+bb2: ; preds = %bb1, %bb
+ %tmp = phi i64 [ undef, %bb1 ], [ undef, %bb ]
+ unreachable
+
+bb3: ; preds = %bb1, %bb
+ unreachable
+}
diff --git a/test/Transforms/Mem2Reg/debug-alloca-phi.ll b/test/Transforms/Mem2Reg/debug-alloca-phi.ll
new file mode 100644
index 000000000000..977365ba4122
--- /dev/null
+++ b/test/Transforms/Mem2Reg/debug-alloca-phi.ll
@@ -0,0 +1,48 @@
+; RUN: opt < %s -mem2reg -S | FileCheck %s
+source_filename = "bugpoint-output.bc"
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.12.0"
+
+define void @scan() #0 !dbg !12 {
+entry:
+ %entry1 = alloca i8, align 8
+ call void @llvm.dbg.declare(metadata i8* %entry1, metadata !18, metadata !19), !dbg !20
+ store i8 0, i8* %entry1, align 8, !dbg !20
+ br label %for.cond, !dbg !20
+
+for.cond:
+; CHECK: %[[PHI:.*]] = phi i8 [ 0, %entry ], [ %0, %for.cond ]
+ %entryN = load i8, i8* %entry1, align 8, !dbg !20
+; CHECK: call void @llvm.dbg.value(metadata i8 %[[PHI]], i64 0,
+; CHECK-SAME: metadata ![[EXPR:[0-9]+]])
+ %0 = add i8 %entryN, 1
+; CHECK: %0 = add i8 %[[PHI]], 1
+; CHECK: call void @llvm.dbg.value(metadata i8 %0, i64 0,
+; CHECK-SAME: metadata ![[EXPR]])
+ store i8 %0, i8* %entry1, align 8, !dbg !20
+ br label %for.cond, !dbg !20
+}
+
+; CHECK: ![[EXPR]] = !DIExpression()
+
+declare void @llvm.dbg.declare(metadata, metadata, metadata) #1
+
+attributes #0 = { nounwind ssp uwtable }
+attributes #1 = { nounwind readnone }
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!10, !11}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "adrian", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug)
+!1 = !DIFile(filename: "<stdin>", directory: "/")
+!2 = !{}
+!4 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char)
+!10 = !{i32 2, !"Debug Info Version", i32 3}
+!11 = !{i32 1, !"PIC Level", i32 2}
+!12 = distinct !DISubprogram(name: "scan", scope: !1, file: !1, line: 4, type: !13, isLocal: false, isDefinition: true, scopeLine: 5, flags: DIFlagPrototyped, isOptimized: true, unit: !0, variables: !15)
+!13 = !DISubroutineType(types: !14)
+!14 = !{null, !4, !4}
+!15 = !{!18}
+!18 = !DILocalVariable(name: "entry", scope: !12, file: !1, line: 6, type: !4)
+!19 = !DIExpression()
+!20 = !DILocation(line: 6, scope: !12)
diff --git a/test/Transforms/ObjCARC/clang-arc-use-barrier.ll b/test/Transforms/ObjCARC/clang-arc-use-barrier.ll
new file mode 100644
index 000000000000..98d49ec512ee
--- /dev/null
+++ b/test/Transforms/ObjCARC/clang-arc-use-barrier.ll
@@ -0,0 +1,45 @@
+; RUN: opt -objc-arc -S %s | FileCheck %s
+
+%0 = type opaque
+
+; Make sure ARC optimizer doesn't sink @obj_retain past @clang.arc.use.
+
+; CHECK: call i8* @objc_retain(
+; CHECK: call void (...) @clang.arc.use(
+; CHECK: call i8* @objc_retain(
+; CHECK: call void (...) @clang.arc.use(
+
+define void @runTest() local_unnamed_addr {
+ %1 = alloca %0*, align 8
+ %2 = alloca %0*, align 8
+ %3 = tail call %0* @foo0()
+ %4 = bitcast %0* %3 to i8*
+ %5 = tail call i8* @objc_retainAutoreleasedReturnValue(i8* %4)
+ store %0* %3, %0** %1, align 8
+ call void @foo1(%0** nonnull %1)
+ %6 = load %0*, %0** %1, align 8
+ %7 = bitcast %0* %6 to i8*
+ %8 = call i8* @objc_retain(i8* %7)
+ call void (...) @clang.arc.use(%0* %3)
+ call void @objc_release(i8* %4)
+ store %0* %6, %0** %2, align 8
+ call void @foo1(%0** nonnull %2)
+ %9 = load %0*, %0** %2, align 8
+ %10 = bitcast %0* %9 to i8*
+ %11 = call i8* @objc_retain(i8* %10)
+ call void (...) @clang.arc.use(%0* %6)
+ %tmp1 = load %0*, %0** %2, align 8
+ call void @objc_release(i8* %7)
+ call void @foo2(%0* %9)
+ call void @objc_release(i8* %10)
+ ret void
+}
+
+declare %0* @foo0() local_unnamed_addr
+declare void @foo1(%0**) local_unnamed_addr
+declare void @foo2(%0*) local_unnamed_addr
+
+declare i8* @objc_retainAutoreleasedReturnValue(i8*) local_unnamed_addr
+declare i8* @objc_retain(i8*) local_unnamed_addr
+declare void @clang.arc.use(...) local_unnamed_addr
+declare void @objc_release(i8*) local_unnamed_addr
diff --git a/test/Transforms/ObjCARC/intrinsic-use.ll b/test/Transforms/ObjCARC/intrinsic-use.ll
index f75b1872b172..f5956201454c 100644
--- a/test/Transforms/ObjCARC/intrinsic-use.ll
+++ b/test/Transforms/ObjCARC/intrinsic-use.ll
@@ -14,23 +14,20 @@ declare void @test0_helper(i8*, i8**)
; Ensure that we honor clang.arc.use as a use and don't miscompile
; the reduced test case from <rdar://13195034>.
;
-; FIXME: the fact that we re-order retains w.r.t. @clang.arc.use could
-; be problematic if we get run twice, e.g. under LTO.
-;
; CHECK-LABEL: define void @test0(
; CHECK: @objc_retain(i8* %x)
; CHECK-NEXT: store i8* %y, i8** %temp0
; CHECK-NEXT: @objc_retain(i8* %y)
; CHECK-NEXT: call void @test0_helper
; CHECK-NEXT: [[VAL1:%.*]] = load i8*, i8** %temp0
-; CHECK-NEXT: call void (...) @clang.arc.use(i8* %y)
; CHECK-NEXT: @objc_retain(i8* [[VAL1]])
+; CHECK-NEXT: call void (...) @clang.arc.use(i8* %y)
; CHECK-NEXT: @objc_release(i8* %y)
; CHECK-NEXT: store i8* [[VAL1]], i8** %temp1
; CHECK-NEXT: call void @test0_helper
; CHECK-NEXT: [[VAL2:%.*]] = load i8*, i8** %temp1
-; CHECK-NEXT: call void (...) @clang.arc.use(i8* [[VAL1]])
; CHECK-NEXT: @objc_retain(i8* [[VAL2]])
+; CHECK-NEXT: call void (...) @clang.arc.use(i8* [[VAL1]])
; CHECK-NEXT: @objc_release(i8* [[VAL1]])
; CHECK-NEXT: @objc_autorelease(i8* %x)
; CHECK-NEXT: store i8* %x, i8** %out
@@ -71,14 +68,14 @@ entry:
; CHECK-NEXT: @objc_retain(i8* %y)
; CHECK-NEXT: call void @test0_helper
; CHECK-NEXT: [[VAL1:%.*]] = load i8*, i8** %temp0
-; CHECK-NEXT: call void (...) @clang.arc.use(i8* %y)
; CHECK-NEXT: @objc_retain(i8* [[VAL1]])
+; CHECK-NEXT: call void (...) @clang.arc.use(i8* %y)
; CHECK-NEXT: @objc_release(i8* %y)
; CHECK-NEXT: store i8* [[VAL1]], i8** %temp1
; CHECK-NEXT: call void @test0_helper
; CHECK-NEXT: [[VAL2:%.*]] = load i8*, i8** %temp1
-; CHECK-NEXT: call void (...) @clang.arc.use(i8* [[VAL1]])
; CHECK-NEXT: @objc_retain(i8* [[VAL2]])
+; CHECK-NEXT: call void (...) @clang.arc.use(i8* [[VAL1]])
; CHECK-NEXT: @objc_release(i8* [[VAL1]])
; CHECK-NEXT: @objc_autorelease(i8* %x)
; CHECK-NEXT: @objc_release(i8* [[VAL2]])
diff --git a/test/Transforms/PGOProfile/memop_size_opt.ll b/test/Transforms/PGOProfile/memop_size_opt.ll
index c7c42f3c1d33..19a2b7ed293b 100644
--- a/test/Transforms/PGOProfile/memop_size_opt.ll
+++ b/test/Transforms/PGOProfile/memop_size_opt.ll
@@ -4,7 +4,7 @@
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
-define void @foo(i8* %dst, i8* %src, i32* %a, i32 %n) !prof !27 {
+define void @foo(i8* %dst, i8* %src, i8* %dst2, i8* %src2, i32* %a, i32 %n) !prof !27 {
entry:
br label %for.cond
@@ -28,19 +28,29 @@ for.body3:
%add = add nsw i32 %i.0, 1
%conv = sext i32 %add to i64
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 %conv, i32 1, i1 false), !prof !30
+ call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst2, i8* %src2, i64 %conv, i32 1, i1 false), !prof !31
br label %for.inc
-; MEMOP_OPT: switch i64 %conv, label %[[Default_LABEL:.*]] [
+; MEMOP_OPT: switch i64 %conv, label %[[DEFAULT_LABEL:.*]] [
; MEMOP_OPT: i64 1, label %[[CASE_1_LABEL:.*]]
; MEMOP_OPT: ], !prof [[SWITCH_BW:![0-9]+]]
; MEMOP_OPT: [[CASE_1_LABEL]]:
; MEMOP_OPT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 1, i32 1, i1 false)
; MEMOP_OPT: br label %[[MERGE_LABEL:.*]]
-; MEMOP_OPT: [[Default_LABEL]]:
-; MEMOP_OPT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 %conv, i32 1, i1 false)
-; MEMOP_OPT-NOT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 %conv, i32 1, i1 false), !prof
+; MEMOP_OPT: [[DEFAULT_LABEL]]:
+; MEMOP_OPT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 %conv, i32 1, i1 false){{[[:space:]]}}
; MEMOP_OPT: br label %[[MERGE_LABEL]]
; MEMOP_OPT: [[MERGE_LABEL]]:
+; MEMOP_OPT: switch i64 %conv, label %[[DEFAULT_LABEL2:.*]] [
+; MEMOP_OPT: i64 1, label %[[CASE_1_LABEL2:.*]]
+; MEMOP_OPT: ], !prof [[SWITCH_BW:![0-9]+]]
+; MEMOP_OPT: [[CASE_1_LABEL2]]:
+; MEMOP_OPT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst2, i8* %src2, i64 1, i32 1, i1 false)
+; MEMOP_OPT: br label %[[MERGE_LABEL2:.*]]
+; MEMOP_OPT: [[DEFAULT_LABEL2]]:
+; MEMOP_OPT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst2, i8* %src2, i64 %conv, i32 1, i1 false){{[[:space:]]}}
+; MEMOP_OPT: br label %[[MERGE_LABEL2]]
+; MEMOP_OPT: [[MERGE_LABEL2]]:
; MEMOP_OPT: br label %for.inc
; MEMOP_OPT: [[SWITCH_BW]] = !{!"branch_weights", i32 457, i32 99}
@@ -92,6 +102,7 @@ for.end6:
!28 = !{!"branch_weights", i32 20, i32 1}
!29 = !{!"branch_weights", i32 556, i32 20}
!30 = !{!"VP", i32 1, i64 556, i64 1, i64 99, i64 2, i64 88, i64 3, i64 77, i64 9, i64 72, i64 4, i64 66, i64 5, i64 55, i64 6, i64 44, i64 7, i64 33, i64 8, i64 22}
+!31 = !{!"VP", i32 1, i64 556, i64 1, i64 99, i64 2, i64 88, i64 3, i64 77, i64 9, i64 72, i64 4, i64 66, i64 5, i64 55, i64 6, i64 44, i64 7, i64 33, i64 8, i64 22}
declare void @llvm.lifetime.start(i64, i8* nocapture)
diff --git a/test/Transforms/SimplifyCFG/merge-cond-stores.ll b/test/Transforms/SimplifyCFG/merge-cond-stores.ll
index d5d0224a4b24..a4bda96e22a1 100644
--- a/test/Transforms/SimplifyCFG/merge-cond-stores.ll
+++ b/test/Transforms/SimplifyCFG/merge-cond-stores.ll
@@ -36,6 +36,39 @@ end:
ret void
}
+; This is the same as test_simple, but the branch target order has been swapped
+define void @test_simple_commuted(i32* %p, i32 %a, i32 %b) {
+; CHECK-LABEL: @test_simple_commuted(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[X1:%.*]] = icmp eq i32 [[A:%.*]], 0
+; CHECK-NEXT: [[X2:%.*]] = icmp eq i32 [[B:%.*]], 0
+; CHECK-NEXT: [[TMP0:%.*]] = or i1 [[X1]], [[X2]]
+; CHECK-NEXT: br i1 [[TMP0]], label [[TMP1:%.*]], label [[TMP2:%.*]]
+; CHECK: [[DOT:%.*]] = zext i1 [[X2]] to i32
+; CHECK-NEXT: store i32 [[DOT]], i32* [[P:%.*]], align 4
+; CHECK-NEXT: br label [[TMP2]]
+; CHECK: ret void
+;
+entry:
+ %x1 = icmp eq i32 %a, 0
+ br i1 %x1, label %yes1, label %fallthrough
+
+yes1:
+ store i32 0, i32* %p
+ br label %fallthrough
+
+fallthrough:
+ %x2 = icmp eq i32 %b, 0
+ br i1 %x2, label %yes2, label %end
+
+yes2:
+ store i32 1, i32* %p
+ br label %end
+
+end:
+ ret void
+}
+
; This test should entirely fold away, leaving one large basic block.
define void @test_recursive(i32* %p, i32 %a, i32 %b, i32 %c, i32 %d) {
; CHECK-LABEL: @test_recursive(
diff --git a/test/Transforms/StructurizeCFG/invert-compare.ll b/test/Transforms/StructurizeCFG/invert-compare.ll
deleted file mode 100644
index 87d9c6d10569..000000000000
--- a/test/Transforms/StructurizeCFG/invert-compare.ll
+++ /dev/null
@@ -1,60 +0,0 @@
-; RUN: opt -S -structurizecfg %s | FileCheck %s
-
-; CHECK-LABEL: @directly_invert_compare_condition_jump_into_loop(
-; CHECK: %cmp0 = fcmp uge float %arg0, %arg1
-; CHECK-NEXT: br i1 %cmp0, label %end.loop, label %Flow
-define void @directly_invert_compare_condition_jump_into_loop(i32 addrspace(1)* %out, i32 %n, float %arg0, float %arg1) #0 {
-entry:
- br label %for.body
-
-for.body:
- %i = phi i32 [0, %entry], [%i.inc, %end.loop]
- %ptr = getelementptr i32, i32 addrspace(1)* %out, i32 %i
- store i32 %i, i32 addrspace(1)* %ptr, align 4
- %cmp0 = fcmp olt float %arg0, %arg1
- br i1 %cmp0, label %mid.loop, label %end.loop
-
-mid.loop:
- store i32 333, i32 addrspace(1)* %out, align 4
- br label %for.end
-
-end.loop:
- %i.inc = add i32 %i, 1
- %cmp = icmp ne i32 %i.inc, %n
- br i1 %cmp, label %for.body, label %for.end
-
-for.end:
- ret void
-}
-
-; CHECK-LABEL: @invert_multi_use_compare_condition_jump_into_loop(
-; CHECK: %cmp0 = fcmp olt float %arg0, %arg1
-; CHECK: store volatile i1 %cmp0, i1 addrspace(1)* undef
-; CHECK: %0 = xor i1 %cmp0, true
-; CHECK-NEXT: br i1 %0, label %end.loop, label %Flow
-define void @invert_multi_use_compare_condition_jump_into_loop(i32 addrspace(1)* %out, i32 %n, float %arg0, float %arg1) #0 {
-entry:
- br label %for.body
-
-for.body:
- %i = phi i32 [0, %entry], [%i.inc, %end.loop]
- %ptr = getelementptr i32, i32 addrspace(1)* %out, i32 %i
- store i32 %i, i32 addrspace(1)* %ptr, align 4
- %cmp0 = fcmp olt float %arg0, %arg1
- store volatile i1 %cmp0, i1 addrspace(1)* undef
- br i1 %cmp0, label %mid.loop, label %end.loop
-
-mid.loop:
- store i32 333, i32 addrspace(1)* %out, align 4
- br label %for.end
-
-end.loop:
- %i.inc = add i32 %i, 1
- %cmp = icmp ne i32 %i.inc, %n
- br i1 %cmp, label %for.body, label %for.end
-
-for.end:
- ret void
-}
-
-attributes #0 = { nounwind } \ No newline at end of file
diff --git a/test/Transforms/StructurizeCFG/one-loop-multiple-backedges.ll b/test/Transforms/StructurizeCFG/one-loop-multiple-backedges.ll
index aff59642cbcb..668a1e99d814 100644
--- a/test/Transforms/StructurizeCFG/one-loop-multiple-backedges.ll
+++ b/test/Transforms/StructurizeCFG/one-loop-multiple-backedges.ll
@@ -11,8 +11,8 @@ bb:
bb3: ; preds = %bb7, %bb
%tmp = phi i64 [ 0, %bb ], [ %tmp8, %bb7 ]
%tmp4 = fcmp ult float %arg1, 3.500000e+00
-; CHECK: %tmp4 = fcmp oge float %arg1, 3.500000e+00
-; CHECK: br i1 %tmp4, label %bb5, label %Flow
+; CHECK: %0 = xor i1 %tmp4, true
+; CHECK: br i1 %0, label %bb5, label %Flow
br i1 %tmp4, label %bb7, label %bb5
; CHECK: bb5:
@@ -22,8 +22,7 @@ bb5: ; preds = %bb3
br i1 %tmp6, label %bb10, label %bb7
; CHECK: Flow:
-; CHECK: %1 = phi i1 [ %tmp6, %bb5 ], [ %tmp4, %bb3 ]
-; CHECK-NEXT: br i1 %1, label %bb7, label %Flow1
+; CHECK: br i1 %3, label %bb7, label %Flow1
; CHECK: bb7
bb7: ; preds = %bb5, %bb3
@@ -33,10 +32,9 @@ bb7: ; preds = %bb5, %bb3
br i1 %tmp9, label %bb3, label %bb10
; CHECK: Flow1:
-; CHECK: %4 = phi i1 [ %tmp9, %bb7 ], [ true, %Flow ]
-; CHECK-NEXT: br i1 %4, label %bb10, label %bb3
+; CHECK: br i1 %7, label %bb10, label %bb3
-; CHECK: bb10:
+; CHECK: bb10
bb10: ; preds = %bb7, %bb5
%tmp11 = phi i32 [ 15, %bb5 ], [ 255, %bb7 ]
store i32 %tmp11, i32 addrspace(1)* %arg, align 4
diff --git a/test/Transforms/StructurizeCFG/post-order-traversal-bug.ll b/test/Transforms/StructurizeCFG/post-order-traversal-bug.ll
index a8835f19d447..ba9aa2913061 100644
--- a/test/Transforms/StructurizeCFG/post-order-traversal-bug.ll
+++ b/test/Transforms/StructurizeCFG/post-order-traversal-bug.ll
@@ -59,8 +59,7 @@ for.end: ; preds = %for.body.1, %if.the
; CHECK: br i1 %{{[0-9]}}, label %for.body.1, label %Flow2
; CHECK: for.body.1:
-; CHECK: %cmp1.5 = icmp ne i32 %tmp22, %K1
-; CHECK-NEXT: br i1 %cmp1.5, label %for.body.6, label %Flow3
+; CHECK: br i1 %{{[0-9]+}}, label %for.body.6, label %Flow3
for.body.1: ; preds = %if.then, %lor.lhs.false
%best_val.233 = phi float [ %tmp5, %if.then ], [ %best_val.027, %lor.lhs.false ]
%best_count.231 = phi i32 [ %sub4, %if.then ], [ %best_count.025, %lor.lhs.false ]
diff --git a/test/Transforms/Util/libcalls-fast-math-inf-loop.ll b/test/Transforms/Util/libcalls-fast-math-inf-loop.ll
new file mode 100644
index 000000000000..a351fe82173c
--- /dev/null
+++ b/test/Transforms/Util/libcalls-fast-math-inf-loop.ll
@@ -0,0 +1,60 @@
+; RUN: opt -S -instcombine -o - %s | FileCheck %s
+
+; Test that fast math lib call simplification of double math function to float
+; equivalent doesn't occur when the calling function matches the float
+; equivalent math function. Otherwise this can cause the generation of infinite
+; loops when compiled with -O2/3 and fast math.
+
+; Test case C source:
+;
+; extern double exp(double x);
+; inline float expf(float x) { return (float) exp((double) x); }
+; float fn(float f) { return expf(f); }
+;
+; IR generated with command:
+;
+; clang -cc1 -O2 -ffast-math -emit-llvm -disable-llvm-passes -triple x86_64-unknown-unknown -o - <srcfile>
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-unknown"
+
+; Function Attrs: nounwind
+define float @fn(float %f) #0 {
+; CHECK: define float @fn(
+; CHECK: call fast float @expf(
+ %f.addr = alloca float, align 4
+ store float %f, float* %f.addr, align 4, !tbaa !1
+ %1 = load float, float* %f.addr, align 4, !tbaa !1
+ %call = call fast float @expf(float %1) #3
+ ret float %call
+}
+
+; Function Attrs: inlinehint nounwind readnone
+define available_externally float @expf(float %x) #1 {
+; CHECK: define available_externally float @expf(
+; CHECK: fpext float
+; CHECK: call fast double @exp(
+; CHECK: fptrunc double
+ %x.addr = alloca float, align 4
+ store float %x, float* %x.addr, align 4, !tbaa !1
+ %1 = load float, float* %x.addr, align 4, !tbaa !1
+ %conv = fpext float %1 to double
+ %call = call fast double @exp(double %conv) #3
+ %conv1 = fptrunc double %call to float
+ ret float %conv1
+}
+
+; Function Attrs: nounwind readnone
+declare double @exp(double) #2
+
+attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-features"="+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #1 = { inlinehint nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-features"="+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #2 = { nounwind readnone }
+
+!llvm.ident = !{!0}
+
+!0 = !{!"clang version 5.0.0"}
+!1 = !{!2, !2, i64 0}
+!2 = !{!"float", !3, i64 0}
+!3 = !{!"omnipotent char", !4, i64 0}
+!4 = !{!"Simple C/C++ TBAA"}