diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp index c8b9f166b1602..64288fb060fc8 100644 --- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -5462,6 +5462,8 @@ static bool combineInstructionsOverFunction( BranchProbabilityInfo *BPI, ProfileSummaryInfo *PSI, const InstCombineOptions &Opts) { auto &DL = F.getDataLayout(); + bool VerifyFixpoint = Opts.VerifyFixpoint && + !F.hasFnAttribute("instcombine-no-verify-fixpoint"); /// Builder - This is an IRBuilder that automatically inserts new /// instructions into the worklist when they are created. @@ -5486,7 +5488,7 @@ static bool combineInstructionsOverFunction( while (true) { ++Iteration; - if (Iteration > Opts.MaxIterations && !Opts.VerifyFixpoint) { + if (Iteration > Opts.MaxIterations && !VerifyFixpoint) { LLVM_DEBUG(dbgs() << "\n\n[IC] Iteration limit #" << Opts.MaxIterations << " on " << F.getName() << " reached; stopping without verifying fixpoint\n"); @@ -5508,9 +5510,11 @@ static bool combineInstructionsOverFunction( MadeIRChange = true; if (Iteration > Opts.MaxIterations) { report_fatal_error( - "Instruction Combining did not reach a fixpoint after " + - Twine(Opts.MaxIterations) + " iterations. " + - "Use 'instcombine' to suppress this error.", + "Instruction Combining on " + Twine(F.getName()) + + " did not reach a fixpoint after " + Twine(Opts.MaxIterations) + + " iterations. " + + "Use 'instcombine' or function attribute " + "'instcombine-no-verify-fixpoint' to suppress this error.", /*GenCrashDiag=*/false); } } diff --git a/llvm/test/Analysis/ValueTracking/numsignbits-from-assume.ll b/llvm/test/Analysis/ValueTracking/numsignbits-from-assume.ll index 95ac98532da62..5beb0c7cadfba 100644 --- a/llvm/test/Analysis/ValueTracking/numsignbits-from-assume.ll +++ b/llvm/test/Analysis/ValueTracking/numsignbits-from-assume.ll @@ -1,8 +1,5 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt < %s -passes='instcombine' -S | FileCheck %s - -; FIXME: This does not currently reach a fix point, because an assume can only -; be propagated backwards after its argument has been simplified. +; RUN: opt < %s -passes=instcombine -S | FileCheck %s define i32 @computeNumSignBits_add1(i32 %in) { ; CHECK-LABEL: @computeNumSignBits_add1( diff --git a/llvm/test/Transforms/InstCombine/2007-10-31-RangeCrash.ll b/llvm/test/Transforms/InstCombine/2007-10-31-RangeCrash.ll index 8b472aa5af090..b5ae08e1daa3a 100644 --- a/llvm/test/Transforms/InstCombine/2007-10-31-RangeCrash.ll +++ b/llvm/test/Transforms/InstCombine/2007-10-31-RangeCrash.ll @@ -1,13 +1,14 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4 -; RUN: opt < %s -S -passes='instcombine' | FileCheck %s +; RUN: opt < %s -S -passes=instcombine | FileCheck %s ; We do not reach a fixpoint, because we first have to infer nsw on the IV add, ; and could eliminate the icmp slt afterwards, but don't revisit it. target datalayout = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f128:64:128" -define i32 @test() { -; CHECK-LABEL: define i32 @test() { +define i32 @test() "instcombine-no-verify-fixpoint" { +; CHECK-LABEL: define i32 @test( +; CHECK-SAME: ) #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: br i1 true, label [[BB_I:%.*]], label [[CALCULATECOLORSPECIFICBLACKLEVEL_EXIT:%.*]] ; CHECK: bb.i: diff --git a/llvm/test/Transforms/InstCombine/cast_phi.ll b/llvm/test/Transforms/InstCombine/cast_phi.ll index 2819b7d05f7b3..6b05edc31deb8 100644 --- a/llvm/test/Transforms/InstCombine/cast_phi.ll +++ b/llvm/test/Transforms/InstCombine/cast_phi.ll @@ -1,5 +1,5 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt < %s -passes="instcombine" -S | FileCheck %s +; RUN: opt < %s -passes=instcombine -S | FileCheck %s target datalayout = "n32:64" @@ -309,7 +309,7 @@ exit: ret i64 %r } -define i8 @trunc_in_loop_exit_block() { +define i8 @trunc_in_loop_exit_block() "instcombine-no-verify-fixpoint" { ; CHECK-LABEL: @trunc_in_loop_exit_block( ; CHECK-NEXT: entry: ; CHECK-NEXT: br label [[LOOP:%.*]] diff --git a/llvm/test/Transforms/InstCombine/constant-fold-iteration.ll b/llvm/test/Transforms/InstCombine/constant-fold-iteration.ll index 7f800f614c47d..ed4fcc6ecaac7 100644 --- a/llvm/test/Transforms/InstCombine/constant-fold-iteration.ll +++ b/llvm/test/Transforms/InstCombine/constant-fold-iteration.ll @@ -1,11 +1,12 @@ -; RUN: opt < %s -passes='instcombine' -S -debug 2>&1 | FileCheck %s +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 +; RUN: opt < %s -passes=instcombine -S -debug 2>&1 | FileCheck %s ; REQUIRES: asserts target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32" ; This test disables fixpoint verification, because that would cause a second ; iteration for verification. -define i32 @a() nounwind readnone { +define i32 @a() nounwind readnone "instcombine-no-verify-fixpoint" { entry: %cmp = icmp eq i32 0, ptrtoint (ptr @a to i32) %ext = zext i1 %cmp to i32 diff --git a/llvm/test/Transforms/InstCombine/icmp-or.ll b/llvm/test/Transforms/InstCombine/icmp-or.ll index 36b3216196f84..56115f6d7d341 100644 --- a/llvm/test/Transforms/InstCombine/icmp-or.ll +++ b/llvm/test/Transforms/InstCombine/icmp-or.ll @@ -1,5 +1,5 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt < %s -passes='instcombine' -S | FileCheck %s +; RUN: opt < %s -passes=instcombine -S | FileCheck %s declare void @use(i8) @@ -432,7 +432,7 @@ define i1 @icmp_or_xor_2_ne_fail(i64 %x1, i64 %y1, i64 %x2, i64 %y2) { ; simplify `%cmp_1 = icmp eq i64 %xor, 0`, `%xor = xor i64 %x1, %y1` ; has one use which allows for complete simplification (rooted on ; `%or1 = or i1 %cmp, %cmp_1` so we don't end up adding it back). -define i1 @icmp_or_xor_2_3_fail(i64 %x1, i64 %y1, i64 %x2, i64 %y2) { +define i1 @icmp_or_xor_2_3_fail(i64 %x1, i64 %y1, i64 %x2, i64 %y2) "instcombine-no-verify-fixpoint" { ; CHECK-LABEL: @icmp_or_xor_2_3_fail( ; CHECK-NEXT: [[XOR:%.*]] = xor i64 [[X1:%.*]], [[Y1:%.*]] ; CHECK-NEXT: [[XOR1:%.*]] = xor i64 [[X2:%.*]], [[Y2:%.*]] @@ -453,7 +453,7 @@ define i1 @icmp_or_xor_2_3_fail(i64 %x1, i64 %y1, i64 %x2, i64 %y2) { ; negative test - xor multiuse -define i1 @icmp_or_xor_2_4_fail(i64 %x1, i64 %y1, i64 %x2, i64 %y2) { +define i1 @icmp_or_xor_2_4_fail(i64 %x1, i64 %y1, i64 %x2, i64 %y2) "instcombine-no-verify-fixpoint" { ; CHECK-LABEL: @icmp_or_xor_2_4_fail( ; CHECK-NEXT: [[XOR:%.*]] = xor i64 [[X1:%.*]], [[Y1:%.*]] ; CHECK-NEXT: [[XOR1:%.*]] = xor i64 [[X2:%.*]], [[Y2:%.*]] diff --git a/llvm/test/Transforms/InstCombine/pr55228.ll b/llvm/test/Transforms/InstCombine/pr55228.ll index 5e34c074346e3..c959bf16bcb5d 100644 --- a/llvm/test/Transforms/InstCombine/pr55228.ll +++ b/llvm/test/Transforms/InstCombine/pr55228.ll @@ -1,5 +1,5 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt -S -passes='instcombine' < %s | FileCheck %s +; RUN: opt -S -passes=instcombine < %s | FileCheck %s ; This does not reach a fixpoint, because the global initializer is not in ; folded form. This will not happen if preceded by a GlobalOpt run. @@ -9,7 +9,7 @@ target datalayout = "p:8:8" @g = external global i8 @c = constant ptr getelementptr inbounds (i8, ptr @g, i64 1) -define i1 @test(ptr %p) { +define i1 @test(ptr %p) "instcombine-no-verify-fixpoint" { ; CHECK-LABEL: @test( ; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[P:%.*]], getelementptr inbounds (i8, ptr @g, i64 1) ; CHECK-NEXT: ret i1 [[CMP]] diff --git a/llvm/test/Transforms/InstCombine/shift.ll b/llvm/test/Transforms/InstCombine/shift.ll index 558f4ffbfcabe..d699d10d4b3a8 100644 --- a/llvm/test/Transforms/InstCombine/shift.ll +++ b/llvm/test/Transforms/InstCombine/shift.ll @@ -1,8 +1,5 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt < %s -passes='instcombine' -S | FileCheck %s - -; The fuzzer-generated @ashr_out_of_range test case does not reach a fixpoint, -; because a logical and it not relaxed to a bitwise and in one iteration. +; RUN: opt < %s -passes=instcombine -S | FileCheck %s declare void @use(i64) declare void @use_i32(i32) @@ -1735,9 +1732,12 @@ define i177 @lshr_out_of_range2(i177 %Y, ptr %A2, ptr %ptr) { ret i177 %B1 } +; The fuzzer-generated @ashr_out_of_range test case does not reach a fixpoint, +; because a logical and it not relaxed to a bitwise and in one iteration. + ; OSS Fuzz #5032 ; https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=5032 -define void @ashr_out_of_range(ptr %A) { +define void @ashr_out_of_range(ptr %A) "instcombine-no-verify-fixpoint" { ; CHECK-LABEL: @ashr_out_of_range( ; CHECK-NEXT: [[L:%.*]] = load i177, ptr [[A:%.*]], align 4 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i177 [[L]], -1 diff --git a/llvm/test/Transforms/InstCombine/sink_instruction.ll b/llvm/test/Transforms/InstCombine/sink_instruction.ll index dac40852c4bdc..cb9a3069ca5fd 100644 --- a/llvm/test/Transforms/InstCombine/sink_instruction.ll +++ b/llvm/test/Transforms/InstCombine/sink_instruction.ll @@ -1,9 +1,5 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt -passes='instcombine' -S < %s | FileCheck %s - -; We fail to reach a fixpoint, because sunk instructions get revisited too -; early. In @test2 the sunk add is revisited before the dominating condition -; is visited and added to the DomConditionCache. +; RUN: opt -passes=instcombine -S < %s | FileCheck %s ;; This tests that the instructions in the entry blocks are sunk into each ;; arm of the 'if'. @@ -31,9 +27,12 @@ endif: ; preds = %entry ret i32 %tmp.2 } +; We fail to reach a fixpoint, because sunk instructions get revisited too +; early. In @test2 the sunk add is revisited before the dominating condition +; is visited and added to the DomConditionCache. ;; PHI use, sink divide before call. -define i32 @test2(i32 %x) nounwind ssp { +define i32 @test2(i32 %x) nounwind ssp "instcombine-no-verify-fixpoint" { ; CHECK-LABEL: @test2( ; CHECK-NEXT: entry: ; CHECK-NEXT: br label [[BB:%.*]] diff --git a/llvm/test/Transforms/InstCombine/zext-or-icmp.ll b/llvm/test/Transforms/InstCombine/zext-or-icmp.ll index acf547b55722f..feb4be9e37050 100644 --- a/llvm/test/Transforms/InstCombine/zext-or-icmp.ll +++ b/llvm/test/Transforms/InstCombine/zext-or-icmp.ll @@ -1,5 +1,5 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt < %s -passes='instcombine' -S | FileCheck %s +; RUN: opt < %s -passes=instcombine -S | FileCheck %s define i8 @zext_or_icmp_icmp(i8 %a, i8 %b) { ; CHECK-LABEL: @zext_or_icmp_icmp( @@ -168,7 +168,7 @@ define i32 @PR49475(i32 %x, i16 %y) { ; This would infinite-loop. -define i8 @PR49475_infloop(i32 %t0, i16 %insert, i64 %e, i8 %i162) { +define i8 @PR49475_infloop(i32 %t0, i16 %insert, i64 %e, i8 %i162) "instcombine-no-verify-fixpoint" { ; CHECK-LABEL: @PR49475_infloop( ; CHECK-NEXT: [[B2:%.*]] = icmp eq i16 [[INSERT:%.*]], 0 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[T0:%.*]], 1 diff --git a/llvm/test/Transforms/PGOProfile/chr.ll b/llvm/test/Transforms/PGOProfile/chr.ll index 34e39fe37979a..46f9a2bde7a23 100644 --- a/llvm/test/Transforms/PGOProfile/chr.ll +++ b/llvm/test/Transforms/PGOProfile/chr.ll @@ -1,8 +1,5 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt < %s -passes='require,function(chr,instcombine,simplifycfg)' -S | FileCheck %s - -; FIXME: This does not currently reach a fix point, because we don't make use -; of a freeze that is pushed up the instruction chain later. +; RUN: opt < %s -passes='require,function(chr,instcombine,simplifycfg)' -S | FileCheck %s declare void @foo() declare void @bar() @@ -1910,6 +1907,9 @@ bb4: ret i32 %v13 } +; FIXME: This does not currently reach a fix point, because we don't make use +; of a freeze that is pushed up the instruction chain later. + ; Test the case where two scopes share a common instruction to hoist (%cmp.i). ; Two scopes would hoist it to their hoist points, but since the outer scope ; hoists (entry/bb6-9) it first to its hoist point, it'd be wrong (causing bad @@ -1928,7 +1928,7 @@ bb4: ; foo(); ; } ; return 45; -define i32 @test_chr_21(i64 %i, i64 %k, i64 %j) !prof !14 { +define i32 @test_chr_21(i64 %i, i64 %k, i64 %j) "instcombine-no-verify-fixpoint" !prof !14 { ; CHECK-LABEL: @test_chr_21( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[I_FR:%.*]] = freeze i64 [[I:%.*]] diff --git a/llvm/test/Transforms/SimpleLoopUnswitch/2007-08-01-LCSSA.ll b/llvm/test/Transforms/SimpleLoopUnswitch/2007-08-01-LCSSA.ll index 9e4b33d4c4d5e..fb342322b2da7 100644 --- a/llvm/test/Transforms/SimpleLoopUnswitch/2007-08-01-LCSSA.ll +++ b/llvm/test/Transforms/SimpleLoopUnswitch/2007-08-01-LCSSA.ll @@ -1,5 +1,5 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4 -; RUN: opt < %s -S -passes='loop(simple-loop-unswitch),instcombine' -verify-memoryssa | FileCheck %s +; RUN: opt < %s -S -passes='loop(simple-loop-unswitch),instcombine' -verify-memoryssa | FileCheck %s ; We do not reach a fixpoint, because we first have to infer nsw on the IV add, ; and could eliminate the icmp slt afterwards, but don't revisit it. @@ -8,9 +8,9 @@ declare i32 @strcmp(ptr, ptr) -define i32 @_ZN9Generator6strregEPKc(ptr %this, ptr %s) { +define i32 @_ZN9Generator6strregEPKc(ptr %this, ptr %s) "instcombine-no-verify-fixpoint" { ; CHECK-LABEL: define i32 @_ZN9Generator6strregEPKc( -; CHECK-SAME: ptr [[THIS:%.*]], ptr [[S:%.*]]) { +; CHECK-SAME: ptr [[THIS:%.*]], ptr [[S:%.*]]) #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[TMP122:%.*]] = icmp eq ptr [[S]], null ; CHECK-NEXT: br label [[BB184:%.*]]