diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -85,14 +85,14 @@ #define DEBUG_TYPE "simplifycfg" -// Chosen as 2 so as to be cheap, but still to have enough power to fold -// a select, so the "clamp" idiom (of a min followed by a max) will be caught. -// To catch this, we need to fold a compare and a select, hence '2' being the -// minimum reasonable default. +// Chosen as 3 so as to be cheap, but still to have enough power to fold +// a check for the lack of unsigned multiplication overflow. To catch this, +// we need to fold a 'not', 'extractvalue', '@llvm.umul.with.overflow', +// hence '3' being the minimum reasonable default. static cl::opt PHINodeFoldingThreshold( - "phi-node-folding-threshold", cl::Hidden, cl::init(2), + "phi-node-folding-threshold", cl::Hidden, cl::init(3), cl::desc( - "Control the amount of phi node folding to perform (default = 2)")); + "Control the amount of phi node folding to perform (default = 3)")); static cl::opt DupRet( "simplifycfg-dup-ret", cl::Hidden, cl::init(false), diff --git a/llvm/test/Transforms/IndVarSimplify/loop_evaluate_1.ll b/llvm/test/Transforms/IndVarSimplify/loop_evaluate_1.ll --- a/llvm/test/Transforms/IndVarSimplify/loop_evaluate_1.ll +++ b/llvm/test/Transforms/IndVarSimplify/loop_evaluate_1.ll @@ -28,14 +28,10 @@ ; CHECK-LABEL: @test2( ; CHECK-NEXT: bb: ; CHECK-NEXT: [[TMP:%.*]] = icmp ugt i32 [[ARG:%.*]], 10 -; CHECK-NEXT: br i1 [[TMP]], label [[BB1_PREHEADER:%.*]], label [[BB7:%.*]] -; CHECK: bb1.preheader: ; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[ARG]], -11 ; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[TMP0]], 1 ; CHECK-NEXT: [[TMP2:%.*]] = add nuw i32 [[TMP1]], 1 -; CHECK-NEXT: br label [[BB7]] -; CHECK: bb7: -; CHECK-NEXT: [[TMP8:%.*]] = phi i32 [ 0, [[BB:%.*]] ], [ [[TMP2]], [[BB1_PREHEADER]] ] +; CHECK-NEXT: [[TMP8:%.*]] = select i1 [[TMP]], i32 [[TMP2]], i32 0 ; CHECK-NEXT: ret i32 [[TMP8]] ; bb: diff --git a/llvm/test/Transforms/PhaseOrdering/unsigned-multiply-overflow-check.ll b/llvm/test/Transforms/PhaseOrdering/unsigned-multiply-overflow-check.ll --- a/llvm/test/Transforms/PhaseOrdering/unsigned-multiply-overflow-check.ll +++ b/llvm/test/Transforms/PhaseOrdering/unsigned-multiply-overflow-check.ll @@ -117,18 +117,23 @@ ; INSTCOMBINEONLY-NEXT: [[T6:%.*]] = phi i1 [ true, [[BB:%.*]] ], [ [[PHITMP]], [[BB2]] ] ; INSTCOMBINEONLY-NEXT: ret i1 [[T6]] ; -; INSTCOMBINESIMPLIFYCFGDEFAULT-LABEL: @will_overflow( -; INSTCOMBINESIMPLIFYCFGDEFAULT-NEXT: bb: -; INSTCOMBINESIMPLIFYCFGDEFAULT-NEXT: [[T0:%.*]] = icmp eq i64 [[ARG:%.*]], 0 -; INSTCOMBINESIMPLIFYCFGDEFAULT-NEXT: br i1 [[T0]], label [[BB5:%.*]], label [[BB2:%.*]] -; INSTCOMBINESIMPLIFYCFGDEFAULT: bb2: -; INSTCOMBINESIMPLIFYCFGDEFAULT-NEXT: [[UMUL:%.*]] = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 [[ARG]], i64 [[ARG1:%.*]]) -; INSTCOMBINESIMPLIFYCFGDEFAULT-NEXT: [[UMUL_OV:%.*]] = extractvalue { i64, i1 } [[UMUL]], 1 -; INSTCOMBINESIMPLIFYCFGDEFAULT-NEXT: [[PHITMP:%.*]] = xor i1 [[UMUL_OV]], true -; INSTCOMBINESIMPLIFYCFGDEFAULT-NEXT: br label [[BB5]] -; INSTCOMBINESIMPLIFYCFGDEFAULT: bb5: -; INSTCOMBINESIMPLIFYCFGDEFAULT-NEXT: [[T6:%.*]] = phi i1 [ true, [[BB:%.*]] ], [ [[PHITMP]], [[BB2]] ] -; INSTCOMBINESIMPLIFYCFGDEFAULT-NEXT: ret i1 [[T6]] +; INSTCOMBINESIMPLIFYCFGONLY-LABEL: @will_overflow( +; INSTCOMBINESIMPLIFYCFGONLY-NEXT: bb: +; INSTCOMBINESIMPLIFYCFGONLY-NEXT: [[T0:%.*]] = icmp eq i64 [[ARG:%.*]], 0 +; INSTCOMBINESIMPLIFYCFGONLY-NEXT: [[UMUL:%.*]] = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 [[ARG]], i64 [[ARG1:%.*]]) +; INSTCOMBINESIMPLIFYCFGONLY-NEXT: [[UMUL_OV:%.*]] = extractvalue { i64, i1 } [[UMUL]], 1 +; INSTCOMBINESIMPLIFYCFGONLY-NEXT: [[PHITMP:%.*]] = xor i1 [[UMUL_OV]], true +; INSTCOMBINESIMPLIFYCFGONLY-NEXT: [[T6:%.*]] = select i1 [[T0]], i1 true, i1 [[PHITMP]] +; INSTCOMBINESIMPLIFYCFGONLY-NEXT: ret i1 [[T6]] +; +; INSTCOMBINESIMPLIFYCFGINSTCOMBINE-LABEL: @will_overflow( +; INSTCOMBINESIMPLIFYCFGINSTCOMBINE-NEXT: bb: +; INSTCOMBINESIMPLIFYCFGINSTCOMBINE-NEXT: [[T0:%.*]] = icmp eq i64 [[ARG:%.*]], 0 +; INSTCOMBINESIMPLIFYCFGINSTCOMBINE-NEXT: [[UMUL:%.*]] = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 [[ARG]], i64 [[ARG1:%.*]]) +; INSTCOMBINESIMPLIFYCFGINSTCOMBINE-NEXT: [[UMUL_OV:%.*]] = extractvalue { i64, i1 } [[UMUL]], 1 +; INSTCOMBINESIMPLIFYCFGINSTCOMBINE-NEXT: [[PHITMP:%.*]] = xor i1 [[UMUL_OV]], true +; INSTCOMBINESIMPLIFYCFGINSTCOMBINE-NEXT: [[T6:%.*]] = or i1 [[T0]], [[PHITMP]] +; INSTCOMBINESIMPLIFYCFGINSTCOMBINE-NEXT: ret i1 [[T6]] ; ; INSTCOMBINESIMPLIFYCFGCOSTLYONLY-LABEL: @will_overflow( ; INSTCOMBINESIMPLIFYCFGCOSTLYONLY-NEXT: bb: diff --git a/llvm/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll b/llvm/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll --- a/llvm/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll +++ b/llvm/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll @@ -1437,14 +1437,10 @@ ; CHECK-LABEL: @no_reuse_cmp2( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[EC:%.*]] = icmp ne i32 [[Y:%.*]], 0 -; CHECK-NEXT: br i1 [[EC]], label [[SWITCH_ENTRY:%.*]], label [[SW_EPILOG:%.*]] -; CHECK: switch.entry: ; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[X:%.*]], 4 ; CHECK-NEXT: [[SWITCH_OFFSET:%.*]] = add i32 [[X]], 10 ; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[TMP0]], i32 [[SWITCH_OFFSET]], i32 0 -; CHECK-NEXT: br label [[SW_EPILOG]] -; CHECK: sw.epilog: -; CHECK-NEXT: [[R_0:%.*]] = phi i32 [ 100, [[ENTRY:%.*]] ], [ [[SPEC_SELECT]], [[SWITCH_ENTRY]] ] +; CHECK-NEXT: [[R_0:%.*]] = select i1 [[EC]], i32 [[SPEC_SELECT]], i32 100 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[R_0]], 0 ; CHECK-NEXT: [[DOTR_0:%.*]] = select i1 [[CMP]], i32 100, i32 [[R_0]] ; CHECK-NEXT: ret i32 [[DOTR_0]] diff --git a/llvm/test/Transforms/SimplifyCFG/signbit-like-value-extension.ll b/llvm/test/Transforms/SimplifyCFG/signbit-like-value-extension.ll --- a/llvm/test/Transforms/SimplifyCFG/signbit-like-value-extension.ll +++ b/llvm/test/Transforms/SimplifyCFG/signbit-like-value-extension.ll @@ -11,14 +11,10 @@ ; CHECK-NEXT: [[SKIPNBITS:%.*]] = sub i32 32, [[NBITS:%.*]] ; CHECK-NEXT: [[VALUE:%.*]] = lshr i32 [[STORAGE:%.*]], [[SKIPNBITS]] ; CHECK-NEXT: [[SHOULDEXTEND:%.*]] = icmp sgt i32 [[STORAGE]], -1 -; CHECK-NEXT: br i1 [[SHOULDEXTEND]], label [[EXTEND:%.*]], label [[END:%.*]] -; CHECK: extend: ; CHECK-NEXT: [[HIGHBITMASK:%.*]] = shl nsw i32 -1, [[NBITS]] ; CHECK-NEXT: [[HIGHBITMASKPLUSONE:%.*]] = add nsw i32 [[HIGHBITMASK]], 1 ; CHECK-NEXT: [[EXTENDED:%.*]] = add i32 [[HIGHBITMASKPLUSONE]], [[VALUE]] -; CHECK-NEXT: br label [[END]] -; CHECK: end: -; CHECK-NEXT: [[RES:%.*]] = phi i32 [ [[EXTENDED]], [[EXTEND]] ], [ [[VALUE]], [[BB:%.*]] ] +; CHECK-NEXT: [[RES:%.*]] = select i1 [[SHOULDEXTEND]], i32 [[EXTENDED]], i32 [[VALUE]] ; CHECK-NEXT: ret i32 [[RES]] ; bb: diff --git a/llvm/test/Transforms/SimplifyCFG/unsigned-multiplication-will-overflow.ll b/llvm/test/Transforms/SimplifyCFG/unsigned-multiplication-will-overflow.ll --- a/llvm/test/Transforms/SimplifyCFG/unsigned-multiplication-will-overflow.ll +++ b/llvm/test/Transforms/SimplifyCFG/unsigned-multiplication-will-overflow.ll @@ -8,18 +8,27 @@ ; produced llvm.umul.with.overflow. define i1 @will_overflow(i64 %size, i64 %nmemb) { -; DEFAULT-LABEL: @will_overflow( -; DEFAULT-NEXT: entry: -; DEFAULT-NEXT: [[CMP:%.*]] = icmp eq i64 [[SIZE:%.*]], 0 -; DEFAULT-NEXT: br i1 [[CMP]], label [[LAND_END:%.*]], label [[LAND_RHS:%.*]] -; DEFAULT: land.rhs: -; DEFAULT-NEXT: [[UMUL:%.*]] = tail call { i64, i1 } @llvm.umul.with.overflow.i64(i64 [[SIZE]], i64 [[NMEMB:%.*]]) -; DEFAULT-NEXT: [[UMUL_OV:%.*]] = extractvalue { i64, i1 } [[UMUL]], 1 -; DEFAULT-NEXT: [[UMUL_NOT_OV:%.*]] = xor i1 [[UMUL_OV]], true -; DEFAULT-NEXT: br label [[LAND_END]] -; DEFAULT: land.end: -; DEFAULT-NEXT: [[TMP0:%.*]] = phi i1 [ true, [[ENTRY:%.*]] ], [ [[UMUL_NOT_OV]], [[LAND_RHS]] ] -; DEFAULT-NEXT: ret i1 [[TMP0]] +; FALLBACK0-LABEL: @will_overflow( +; FALLBACK0-NEXT: entry: +; FALLBACK0-NEXT: [[CMP:%.*]] = icmp eq i64 [[SIZE:%.*]], 0 +; FALLBACK0-NEXT: [[UMUL:%.*]] = tail call { i64, i1 } @llvm.umul.with.overflow.i64(i64 [[SIZE]], i64 [[NMEMB:%.*]]) +; FALLBACK0-NEXT: [[UMUL_OV:%.*]] = extractvalue { i64, i1 } [[UMUL]], 1 +; FALLBACK0-NEXT: [[UMUL_NOT_OV:%.*]] = xor i1 [[UMUL_OV]], true +; FALLBACK0-NEXT: [[TMP0:%.*]] = select i1 [[CMP]], i1 true, i1 [[UMUL_NOT_OV]] +; FALLBACK0-NEXT: ret i1 [[TMP0]] +; +; FALLBACK1-LABEL: @will_overflow( +; FALLBACK1-NEXT: entry: +; FALLBACK1-NEXT: [[CMP:%.*]] = icmp eq i64 [[SIZE:%.*]], 0 +; FALLBACK1-NEXT: br i1 [[CMP]], label [[LAND_END:%.*]], label [[LAND_RHS:%.*]] +; FALLBACK1: land.rhs: +; FALLBACK1-NEXT: [[UMUL:%.*]] = tail call { i64, i1 } @llvm.umul.with.overflow.i64(i64 [[SIZE]], i64 [[NMEMB:%.*]]) +; FALLBACK1-NEXT: [[UMUL_OV:%.*]] = extractvalue { i64, i1 } [[UMUL]], 1 +; FALLBACK1-NEXT: [[UMUL_NOT_OV:%.*]] = xor i1 [[UMUL_OV]], true +; FALLBACK1-NEXT: br label [[LAND_END]] +; FALLBACK1: land.end: +; FALLBACK1-NEXT: [[TMP0:%.*]] = phi i1 [ true, [[ENTRY:%.*]] ], [ [[UMUL_NOT_OV]], [[LAND_RHS]] ] +; FALLBACK1-NEXT: ret i1 [[TMP0]] ; ; COSTLY-LABEL: @will_overflow( ; COSTLY-NEXT: entry: