diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp index 5ee3bb1abe86e..1c512ec1e21bb 100644 --- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -4961,63 +4961,68 @@ Instruction *InstCombinerImpl::visitLandingPadInst(LandingPadInst &LI) { Value * InstCombinerImpl::pushFreezeToPreventPoisonFromPropagating(FreezeInst &OrigFI) { // Try to push freeze through instructions that propagate but don't produce - // poison as far as possible. If an operand of freeze follows three - // conditions 1) one-use, 2) does not produce poison, and 3) has all but one - // guaranteed-non-poison operands then push the freeze through to the one - // operand that is not guaranteed non-poison. The actual transform is as - // follows. - // Op1 = ... ; Op1 can be posion - // Op0 = Inst(Op1, NonPoisonOps...) ; Op0 has only one use and only have - // ; single guaranteed-non-poison operands + // poison as far as possible. If an operand of freeze does not produce poison + // then push the freeze through to the operands that are not guaranteed + // non-poison. The actual transform is as follows. + // Op1 = ... ; Op1 can be poison + // Op0 = Inst(Op1, NonPoisonOps...) // ... = Freeze(Op0) // => // Op1 = ... // Op1.fr = Freeze(Op1) // ... = Inst(Op1.fr, NonPoisonOps...) - auto *OrigOp = OrigFI.getOperand(0); - auto *OrigOpInst = dyn_cast(OrigOp); - // While we could change the other users of OrigOp to use freeze(OrigOp), that - // potentially reduces their optimization potential, so let's only do this iff - // the OrigOp is only used by the freeze. - if (!OrigOpInst || !OrigOpInst->hasOneUse() || isa(OrigOp)) - return nullptr; + auto CanPushFreeze = [](Value *V) { + if (!isa(V) || isa(V)) + return false; - // We can't push the freeze through an instruction which can itself create - // poison. If the only source of new poison is flags, we can simply - // strip them (since we know the only use is the freeze and nothing can - // benefit from them.) - if (canCreateUndefOrPoison(cast(OrigOp), - /*ConsiderFlagsAndMetadata*/ false)) - return nullptr; + // We can't push the freeze through an instruction which can itself create + // poison. If the only source of new poison is flags, we can simply + // strip them (since we know the only use is the freeze and nothing can + // benefit from them.) + return !canCreateUndefOrPoison(cast(V), + /*ConsiderFlagsAndMetadata*/ false); + }; - // If operand is guaranteed not to be poison, there is no need to add freeze - // to the operand. So we first find the operand that is not guaranteed to be - // poison. - Value *MaybePoisonOperand = nullptr; - for (Value *V : OrigOpInst->operands()) { - if (isa(V) || isGuaranteedNotToBeUndefOrPoison(V) || - // Treat identical operands as a single operand. - (MaybePoisonOperand && MaybePoisonOperand == V)) + // Pushing freezes up long instruction chains can be expensive. Instead, + // we directly push the freeze all the way to the leaves. However, we leave + // deduplication of freezes on the same value for freezeOtherUses(). + Use *OrigUse = &OrigFI.getOperandUse(0); + SmallPtrSet Visited; + SmallVector Worklist; + Worklist.push_back(OrigUse); + while (!Worklist.empty()) { + auto *U = Worklist.pop_back_val(); + Value *V = U->get(); + if (!CanPushFreeze(V)) { + // If we can't push through the original instruction, abort the transform. + if (U == OrigUse) + return nullptr; + + auto *UserI = cast(U->getUser()); + Builder.SetInsertPoint(UserI); + Value *Frozen = Builder.CreateFreeze(V, V->getName() + ".fr"); + U->set(Frozen); continue; - if (!MaybePoisonOperand) - MaybePoisonOperand = V; - else - return nullptr; - } + } - OrigOpInst->dropPoisonGeneratingAnnotations(); + auto *I = cast(V); + if (!Visited.insert(I).second) + continue; - // If all operands are guaranteed to be non-poison, we can drop freeze. - if (!MaybePoisonOperand) - return OrigOp; + // reverse() to emit freezes in a more natural order. + for (Use &Op : reverse(I->operands())) { + Value *OpV = Op.get(); + if (isa(OpV) || isGuaranteedNotToBeUndefOrPoison(OpV)) + continue; + Worklist.push_back(&Op); + } - Builder.SetInsertPoint(OrigOpInst); - Value *FrozenMaybePoisonOperand = Builder.CreateFreeze( - MaybePoisonOperand, MaybePoisonOperand->getName() + ".fr"); + I->dropPoisonGeneratingAnnotations(); + this->Worklist.add(I); + } - OrigOpInst->replaceUsesOfWith(MaybePoisonOperand, FrozenMaybePoisonOperand); - return OrigOp; + return OrigUse->get(); } Instruction *InstCombinerImpl::foldFreezeIntoRecurrence(FreezeInst &FI, diff --git a/llvm/test/Transforms/InstCombine/freeze-fp-ops.ll b/llvm/test/Transforms/InstCombine/freeze-fp-ops.ll index 15753ca3fac3d..08f81e6db9bb5 100644 --- a/llvm/test/Transforms/InstCombine/freeze-fp-ops.ll +++ b/llvm/test/Transforms/InstCombine/freeze-fp-ops.ll @@ -163,8 +163,9 @@ define float @freeze_sqrt(float %arg) { define float @freeze_powi(float %arg0, i32 %arg1) { ; CHECK-LABEL: define float @freeze_powi( ; CHECK-SAME: float [[ARG0:%.*]], i32 [[ARG1:%.*]]) { -; CHECK-NEXT: [[OP:%.*]] = call float @llvm.powi.f32.i32(float [[ARG0]], i32 [[ARG1]]) -; CHECK-NEXT: [[FREEZE:%.*]] = freeze float [[OP]] +; CHECK-NEXT: [[ARG0_FR:%.*]] = freeze float [[ARG0]] +; CHECK-NEXT: [[ARG1_FR:%.*]] = freeze i32 [[ARG1]] +; CHECK-NEXT: [[FREEZE:%.*]] = call float @llvm.powi.f32.i32(float [[ARG0_FR]], i32 [[ARG1_FR]]) ; CHECK-NEXT: ret float [[FREEZE]] ; %op = call float @llvm.powi.f32.i32(float %arg0, i32 %arg1) diff --git a/llvm/test/Transforms/InstCombine/freeze.ll b/llvm/test/Transforms/InstCombine/freeze.ll index ff234bb09336d..b29421a655fa8 100644 --- a/llvm/test/Transforms/InstCombine/freeze.ll +++ b/llvm/test/Transforms/InstCombine/freeze.ll @@ -106,11 +106,11 @@ define <3 x i4> @partial_undef_vec() { ; Move the freeze forward to prevent poison from spreading. define i32 @early_freeze_test1(i32 %x, i32 %y) { -; CHECK-LABEL: define i32 @early_freeze_test1( -; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[V1:%.*]] = add i32 [[X]], [[Y]] -; CHECK-NEXT: [[V1_FR:%.*]] = freeze i32 [[V1]] -; CHECK-NEXT: [[V2:%.*]] = shl i32 [[V1_FR]], 1 +; CHECK-LABEL: @early_freeze_test1( +; CHECK-NEXT: [[X_FR:%.*]] = freeze i32 [[X:%.*]] +; CHECK-NEXT: [[Y_FR:%.*]] = freeze i32 [[Y:%.*]] +; CHECK-NEXT: [[V1:%.*]] = add i32 [[X_FR]], [[Y_FR]] +; CHECK-NEXT: [[V2:%.*]] = shl i32 [[V1]], 1 ; CHECK-NEXT: [[V3:%.*]] = and i32 [[V2]], 2 ; CHECK-NEXT: ret i32 [[V3]] ; @@ -153,9 +153,8 @@ define i32 @early_freeze_test3(i32 %v1) { } define i32 @early_freeze_test4(i32 %v1) { -; CHECK-LABEL: define i32 @early_freeze_test4( -; CHECK-SAME: i32 [[V1:%.*]]) { -; CHECK-NEXT: [[V1_FR:%.*]] = freeze i32 [[V1]] +; CHECK-LABEL: @early_freeze_test4( +; CHECK-NEXT: [[V1_FR:%.*]] = freeze i32 [[V1:%.*]] ; CHECK-NEXT: [[V2:%.*]] = mul i32 [[V1_FR]], [[V1_FR]] ; CHECK-NEXT: ret i32 [[V2]] ; @@ -938,21 +937,20 @@ exit: ; preds = %loop } ; The recurrence for the GEP offset can't produce poison so the freeze should -; be pushed through to the ptr, but this is not currently supported. +; be pushed through to the ptr. define void @fold_phi_gep_phi_offset(ptr %init, ptr %end, i64 noundef %n) { -; CHECK-LABEL: define void @fold_phi_gep_phi_offset( -; CHECK-SAME: ptr [[INIT:%.*]], ptr [[END:%.*]], i64 noundef [[N:%.*]]) { -; CHECK-NEXT: [[ENTRY:.*]]: -; CHECK-NEXT: br label %[[LOOP:.*]] -; CHECK: [[LOOP]]: -; CHECK-NEXT: [[I:%.*]] = phi ptr [ [[INIT]], %[[ENTRY]] ], [ [[I_NEXT_FR:%.*]], %[[LOOP]] ] -; CHECK-NEXT: [[OFF:%.*]] = phi i64 [ [[N]], %[[ENTRY]] ], [ [[OFF_NEXT:%.*]], %[[LOOP]] ] +; CHECK-LABEL: @fold_phi_gep_phi_offset( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = freeze ptr [[INIT:%.*]] +; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: loop: +; CHECK-NEXT: [[I:%.*]] = phi ptr [ [[TMP0]], [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[OFF:%.*]] = phi i64 [ [[N:%.*]], [[ENTRY]] ], [ [[OFF_NEXT:%.*]], [[LOOP]] ] ; CHECK-NEXT: [[OFF_NEXT]] = shl i64 [[OFF]], 3 -; CHECK-NEXT: [[I_NEXT:%.*]] = getelementptr i8, ptr [[I]], i64 [[OFF_NEXT]] -; CHECK-NEXT: [[I_NEXT_FR]] = freeze ptr [[I_NEXT]] -; CHECK-NEXT: [[COND:%.*]] = icmp eq ptr [[I_NEXT_FR]], [[END]] -; CHECK-NEXT: br i1 [[COND]], label %[[LOOP]], label %[[EXIT:.*]] -; CHECK: [[EXIT]]: +; CHECK-NEXT: [[I_NEXT]] = getelementptr i8, ptr [[I]], i64 [[OFF_NEXT]] +; CHECK-NEXT: [[COND:%.*]] = icmp eq ptr [[I_NEXT]], [[END:%.*]] +; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]] +; CHECK: exit: ; CHECK-NEXT: ret void ; entry: @@ -971,22 +969,21 @@ exit: ; preds = %loop ret void } -; Offset is still guaranteed not to be poison, so the freeze could be moved -; here if we strip inbounds from the GEP, but this is not currently supported. +; Offset is still guaranteed not to be poison, so the freeze can be moved +; here if we strip inbounds from the GEP. define void @fold_phi_gep_inbounds_phi_offset(ptr %init, ptr %end, i64 noundef %n) { -; CHECK-LABEL: define void @fold_phi_gep_inbounds_phi_offset( -; CHECK-SAME: ptr [[INIT:%.*]], ptr [[END:%.*]], i64 noundef [[N:%.*]]) { -; CHECK-NEXT: [[ENTRY:.*]]: -; CHECK-NEXT: br label %[[LOOP:.*]] -; CHECK: [[LOOP]]: -; CHECK-NEXT: [[I:%.*]] = phi ptr [ [[INIT]], %[[ENTRY]] ], [ [[I_NEXT_FR:%.*]], %[[LOOP]] ] -; CHECK-NEXT: [[OFF:%.*]] = phi i64 [ [[N]], %[[ENTRY]] ], [ [[OFF_NEXT:%.*]], %[[LOOP]] ] +; CHECK-LABEL: @fold_phi_gep_inbounds_phi_offset( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = freeze ptr [[INIT:%.*]] +; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: loop: +; CHECK-NEXT: [[I:%.*]] = phi ptr [ [[TMP0]], [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[OFF:%.*]] = phi i64 [ [[N:%.*]], [[ENTRY]] ], [ [[OFF_NEXT:%.*]], [[LOOP]] ] ; CHECK-NEXT: [[OFF_NEXT]] = shl i64 [[OFF]], 3 -; CHECK-NEXT: [[I_NEXT:%.*]] = getelementptr inbounds i8, ptr [[I]], i64 [[OFF_NEXT]] -; CHECK-NEXT: [[I_NEXT_FR]] = freeze ptr [[I_NEXT]] -; CHECK-NEXT: [[COND:%.*]] = icmp eq ptr [[I_NEXT_FR]], [[END]] -; CHECK-NEXT: br i1 [[COND]], label %[[LOOP]], label %[[EXIT:.*]] -; CHECK: [[EXIT]]: +; CHECK-NEXT: [[I_NEXT]] = getelementptr i8, ptr [[I]], i64 [[OFF_NEXT]] +; CHECK-NEXT: [[COND:%.*]] = icmp eq ptr [[I_NEXT]], [[END:%.*]] +; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]] +; CHECK: exit: ; CHECK-NEXT: ret void ; entry: @@ -1005,21 +1002,21 @@ exit: ; preds = %loop ret void } -; GEP can produce poison, check freeze isn't moved. -define void @cant_fold_phi_gep_phi_offset(ptr %init, ptr %end, i64 %n) { -; CHECK-LABEL: define void @cant_fold_phi_gep_phi_offset( -; CHECK-SAME: ptr [[INIT:%.*]], ptr [[END:%.*]], i64 [[N:%.*]]) { -; CHECK-NEXT: [[ENTRY:.*]]: -; CHECK-NEXT: br label %[[LOOP:.*]] -; CHECK: [[LOOP]]: -; CHECK-NEXT: [[I:%.*]] = phi ptr [ [[INIT]], %[[ENTRY]] ], [ [[I_NEXT_FR:%.*]], %[[LOOP]] ] -; CHECK-NEXT: [[OFF:%.*]] = phi i64 [ [[N]], %[[ENTRY]] ], [ [[OFF_NEXT:%.*]], %[[LOOP]] ] +; Same as previous, but also requires freezing %n. +define void @fold_phi_gep_phi_offset_multiple(ptr %init, ptr %end, i64 %n) { +; CHECK-LABEL: @fold_phi_gep_phi_offset_multiple( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = freeze ptr [[INIT:%.*]] +; CHECK-NEXT: [[TMP1:%.*]] = freeze i64 [[N:%.*]] +; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: loop: +; CHECK-NEXT: [[I:%.*]] = phi ptr [ [[TMP0]], [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[OFF:%.*]] = phi i64 [ [[TMP1]], [[ENTRY]] ], [ [[OFF_NEXT:%.*]], [[LOOP]] ] ; CHECK-NEXT: [[OFF_NEXT]] = shl i64 [[OFF]], 3 -; CHECK-NEXT: [[I_NEXT:%.*]] = getelementptr inbounds i8, ptr [[I]], i64 [[OFF_NEXT]] -; CHECK-NEXT: [[I_NEXT_FR]] = freeze ptr [[I_NEXT]] -; CHECK-NEXT: [[COND:%.*]] = icmp eq ptr [[I_NEXT_FR]], [[END]] -; CHECK-NEXT: br i1 [[COND]], label %[[LOOP]], label %[[EXIT:.*]] -; CHECK: [[EXIT]]: +; CHECK-NEXT: [[I_NEXT]] = getelementptr i8, ptr [[I]], i64 [[OFF_NEXT]] +; CHECK-NEXT: [[COND:%.*]] = icmp eq ptr [[I_NEXT]], [[END:%.*]] +; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]] +; CHECK: exit: ; CHECK-NEXT: ret void ; entry: diff --git a/llvm/test/Transforms/InstCombine/icmp.ll b/llvm/test/Transforms/InstCombine/icmp.ll index 0ee875aed3d0c..0faa7da482ef2 100644 --- a/llvm/test/Transforms/InstCombine/icmp.ll +++ b/llvm/test/Transforms/InstCombine/icmp.ll @@ -5838,10 +5838,9 @@ entry: define i1 @icmp_freeze_sext(i16 %x, i16 %y) { ; CHECK-LABEL: define i1 @icmp_freeze_sext( ; CHECK-SAME: i16 [[X:%.*]], i16 [[Y:%.*]]) { -; CHECK-NEXT: [[CMP1:%.*]] = icmp uge i16 [[X]], [[Y]] -; CHECK-NEXT: [[CMP1_FR:%.*]] = freeze i1 [[CMP1]] -; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i16 [[Y]], 0 -; CHECK-NEXT: [[CMP2:%.*]] = or i1 [[TMP1]], [[CMP1_FR]] +; CHECK-NEXT: [[Y_FR:%.*]] = freeze i16 [[Y]] +; CHECK-NEXT: [[X_FR:%.*]] = freeze i16 [[X]] +; CHECK-NEXT: [[CMP2:%.*]] = icmp uge i16 [[X_FR]], [[Y_FR]] ; CHECK-NEXT: ret i1 [[CMP2]] ; %cmp1 = icmp uge i16 %x, %y diff --git a/llvm/test/Transforms/InstCombine/nsw.ll b/llvm/test/Transforms/InstCombine/nsw.ll index b00f2e58add78..4615ac0ec1ffb 100644 --- a/llvm/test/Transforms/InstCombine/nsw.ll +++ b/llvm/test/Transforms/InstCombine/nsw.ll @@ -255,9 +255,10 @@ define i32 @sub_sub1_nsw_nsw(i32 %a, i32 %b, i32 %c) { define i8 @neg_nsw_freeze(i8 %a1, i8 %a2) { ; CHECK-LABEL: @neg_nsw_freeze( -; CHECK-NEXT: [[A_NEG:%.*]] = sub nsw i8 [[A2:%.*]], [[A1:%.*]] -; CHECK-NEXT: [[FR_NEG:%.*]] = freeze i8 [[A_NEG]] -; CHECK-NEXT: ret i8 [[FR_NEG]] +; CHECK-NEXT: [[A1_FR:%.*]] = freeze i8 [[A1:%.*]] +; CHECK-NEXT: [[A2_FR:%.*]] = freeze i8 [[A2:%.*]] +; CHECK-NEXT: [[A_NEG:%.*]] = sub i8 [[A2_FR]], [[A1_FR]] +; CHECK-NEXT: ret i8 [[A_NEG]] ; %a = sub nsw i8 %a1, %a2 %fr = freeze i8 %a diff --git a/llvm/test/Transforms/InstCombine/select.ll b/llvm/test/Transforms/InstCombine/select.ll index ebfaa1e2198c0..db117aa28cad6 100644 --- a/llvm/test/Transforms/InstCombine/select.ll +++ b/llvm/test/Transforms/InstCombine/select.ll @@ -2847,7 +2847,8 @@ define void @cond_freeze_multipleuses(i8 %x, i8 %y) { define i32 @select_freeze_icmp_eq(i32 %x, i32 %y) { ; CHECK-LABEL: define i32 @select_freeze_icmp_eq( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: ret i32 [[Y]] +; CHECK-NEXT: [[Y_FR:%.*]] = freeze i32 [[Y]] +; CHECK-NEXT: ret i32 [[Y_FR]] ; %c = icmp eq i32 %x, %y %c.fr = freeze i1 %c @@ -2858,7 +2859,8 @@ define i32 @select_freeze_icmp_eq(i32 %x, i32 %y) { define i32 @select_freeze_icmp_ne(i32 %x, i32 %y) { ; CHECK-LABEL: define i32 @select_freeze_icmp_ne( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: ret i32 [[X]] +; CHECK-NEXT: [[X_FR:%.*]] = freeze i32 [[X]] +; CHECK-NEXT: ret i32 [[X_FR]] ; %c = icmp ne i32 %x, %y %c.fr = freeze i1 %c @@ -2869,9 +2871,9 @@ define i32 @select_freeze_icmp_ne(i32 %x, i32 %y) { define i32 @select_freeze_icmp_else(i32 %x, i32 %y) { ; CHECK-LABEL: define i32 @select_freeze_icmp_else( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[X]], [[Y]] -; CHECK-NEXT: [[C_FR:%.*]] = freeze i1 [[C]] -; CHECK-NEXT: [[V:%.*]] = select i1 [[C_FR]], i32 [[X]], i32 [[Y]] +; CHECK-NEXT: [[Y_FR:%.*]] = freeze i32 [[Y]] +; CHECK-NEXT: [[X_FR:%.*]] = freeze i32 [[X]] +; CHECK-NEXT: [[V:%.*]] = call i32 @llvm.umin.i32(i32 [[X_FR]], i32 [[Y_FR]]) ; CHECK-NEXT: ret i32 [[V]] ; %c = icmp ult i32 %x, %y @@ -2885,9 +2887,9 @@ declare void @use_i1_i32(i1, i32) define void @select_freeze_icmp_multuses(i32 %x, i32 %y) { ; CHECK-LABEL: define void @select_freeze_icmp_multuses( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { -; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[X]], [[Y]] -; CHECK-NEXT: [[C_FR:%.*]] = freeze i1 [[C]] -; CHECK-NEXT: [[V:%.*]] = select i1 [[C_FR]], i32 [[X]], i32 [[Y]] +; CHECK-NEXT: [[Y_FR:%.*]] = freeze i32 [[Y]] +; CHECK-NEXT: [[V:%.*]] = freeze i32 [[X]] +; CHECK-NEXT: [[C_FR:%.*]] = icmp ne i32 [[V]], [[Y_FR]] ; CHECK-NEXT: call void @use_i1_i32(i1 [[C_FR]], i32 [[V]]) ; CHECK-NEXT: ret void ; diff --git a/llvm/test/Transforms/InstCombine/sub-of-negatible-inseltpoison.ll b/llvm/test/Transforms/InstCombine/sub-of-negatible-inseltpoison.ll index 537497110cd8a..109669e91d22f 100644 --- a/llvm/test/Transforms/InstCombine/sub-of-negatible-inseltpoison.ll +++ b/llvm/test/Transforms/InstCombine/sub-of-negatible-inseltpoison.ll @@ -1446,8 +1446,9 @@ define i8 @dont_negate_ordinary_select(i8 %x, i8 %y, i8 %z, i1 %c) { define i4 @negate_freeze(i4 %x, i4 %y, i4 %z) { ; CHECK-LABEL: define i4 @negate_freeze( ; CHECK-SAME: i4 [[X:%.*]], i4 [[Y:%.*]], i4 [[Z:%.*]]) { -; CHECK-NEXT: [[T0_NEG:%.*]] = sub i4 [[Y]], [[X]] -; CHECK-NEXT: [[T1_NEG:%.*]] = freeze i4 [[T0_NEG]] +; CHECK-NEXT: [[X_FR:%.*]] = freeze i4 [[X]] +; CHECK-NEXT: [[Y_FR:%.*]] = freeze i4 [[Y]] +; CHECK-NEXT: [[T1_NEG:%.*]] = sub i4 [[Y_FR]], [[X_FR]] ; CHECK-NEXT: [[T2:%.*]] = add i4 [[T1_NEG]], [[Z]] ; CHECK-NEXT: ret i4 [[T2]] ; @@ -1459,8 +1460,9 @@ define i4 @negate_freeze(i4 %x, i4 %y, i4 %z) { define i4 @negate_freeze_extrause(i4 %x, i4 %y, i4 %z) { ; CHECK-LABEL: define i4 @negate_freeze_extrause( ; CHECK-SAME: i4 [[X:%.*]], i4 [[Y:%.*]], i4 [[Z:%.*]]) { -; CHECK-NEXT: [[T0:%.*]] = sub i4 [[X]], [[Y]] -; CHECK-NEXT: [[T1:%.*]] = freeze i4 [[T0]] +; CHECK-NEXT: [[X_FR:%.*]] = freeze i4 [[X]] +; CHECK-NEXT: [[Y_FR:%.*]] = freeze i4 [[Y]] +; CHECK-NEXT: [[T1:%.*]] = sub i4 [[X_FR]], [[Y_FR]] ; CHECK-NEXT: call void @use4(i4 [[T1]]) ; CHECK-NEXT: [[T2:%.*]] = sub i4 [[Z]], [[T1]] ; CHECK-NEXT: ret i4 [[T2]] diff --git a/llvm/test/Transforms/InstCombine/sub-of-negatible.ll b/llvm/test/Transforms/InstCombine/sub-of-negatible.ll index 3a91c14e8ba10..aad006de0e361 100644 --- a/llvm/test/Transforms/InstCombine/sub-of-negatible.ll +++ b/llvm/test/Transforms/InstCombine/sub-of-negatible.ll @@ -1543,8 +1543,9 @@ define <2 x i32> @negate_select_of_negation_poison(<2 x i1> %c, <2 x i32> %x) { define i4 @negate_freeze(i4 %x, i4 %y, i4 %z) { ; CHECK-LABEL: define i4 @negate_freeze( ; CHECK-SAME: i4 [[X:%.*]], i4 [[Y:%.*]], i4 [[Z:%.*]]) { -; CHECK-NEXT: [[T0_NEG:%.*]] = sub i4 [[Y]], [[X]] -; CHECK-NEXT: [[T1_NEG:%.*]] = freeze i4 [[T0_NEG]] +; CHECK-NEXT: [[X_FR:%.*]] = freeze i4 [[X]] +; CHECK-NEXT: [[Y_FR:%.*]] = freeze i4 [[Y]] +; CHECK-NEXT: [[T1_NEG:%.*]] = sub i4 [[Y_FR]], [[X_FR]] ; CHECK-NEXT: [[T2:%.*]] = add i4 [[T1_NEG]], [[Z]] ; CHECK-NEXT: ret i4 [[T2]] ; @@ -1556,8 +1557,9 @@ define i4 @negate_freeze(i4 %x, i4 %y, i4 %z) { define i4 @negate_freeze_extrause(i4 %x, i4 %y, i4 %z) { ; CHECK-LABEL: define i4 @negate_freeze_extrause( ; CHECK-SAME: i4 [[X:%.*]], i4 [[Y:%.*]], i4 [[Z:%.*]]) { -; CHECK-NEXT: [[T0:%.*]] = sub i4 [[X]], [[Y]] -; CHECK-NEXT: [[T1:%.*]] = freeze i4 [[T0]] +; CHECK-NEXT: [[X_FR:%.*]] = freeze i4 [[X]] +; CHECK-NEXT: [[Y_FR:%.*]] = freeze i4 [[Y]] +; CHECK-NEXT: [[T1:%.*]] = sub i4 [[X_FR]], [[Y_FR]] ; CHECK-NEXT: call void @use4(i4 [[T1]]) ; CHECK-NEXT: [[T2:%.*]] = sub i4 [[Z]], [[T1]] ; CHECK-NEXT: ret i4 [[T2]] diff --git a/llvm/test/Transforms/InstCombine/urem-via-cmp-select.ll b/llvm/test/Transforms/InstCombine/urem-via-cmp-select.ll index 64809ddcae3f8..81e35daff6ec6 100644 --- a/llvm/test/Transforms/InstCombine/urem-via-cmp-select.ll +++ b/llvm/test/Transforms/InstCombine/urem-via-cmp-select.ll @@ -96,10 +96,11 @@ define i8 @urem_assume_with_unexpected_const(i8 %x, i8 %n) { define i8 @urem_without_assume(i8 %arg, i8 %arg2) { ; CHECK-LABEL: define i8 @urem_without_assume( ; CHECK-SAME: i8 [[ARG:%.*]], i8 [[ARG2:%.*]]) { -; CHECK-NEXT: [[X:%.*]] = urem i8 [[ARG]], [[ARG2]] -; CHECK-NEXT: [[X_FR:%.*]] = freeze i8 [[X]] +; CHECK-NEXT: [[ARG2_FR:%.*]] = freeze i8 [[ARG2]] +; CHECK-NEXT: [[ARG_FR:%.*]] = freeze i8 [[ARG]] +; CHECK-NEXT: [[X_FR:%.*]] = urem i8 [[ARG_FR]], [[ARG2_FR]] ; CHECK-NEXT: [[ADD:%.*]] = add i8 [[X_FR]], 1 -; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[ADD]], [[ARG2]] +; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[ADD]], [[ARG2_FR]] ; CHECK-NEXT: [[OUT:%.*]] = select i1 [[TMP1]], i8 0, i8 [[ADD]] ; CHECK-NEXT: ret i8 [[OUT]] ; diff --git a/llvm/test/Transforms/LoopVectorize/forked-pointers.ll b/llvm/test/Transforms/LoopVectorize/forked-pointers.ll index 677163b51ec64..efd420c11ef06 100644 --- a/llvm/test/Transforms/LoopVectorize/forked-pointers.ll +++ b/llvm/test/Transforms/LoopVectorize/forked-pointers.ll @@ -17,21 +17,22 @@ target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128" define dso_local void @forked_ptrs_different_base_same_offset(ptr nocapture readonly %Base1, ptr nocapture readonly %Base2, ptr nocapture %Dest, ptr nocapture readonly %Preds) { ; CHECK-LABEL: @forked_ptrs_different_base_same_offset( ; CHECK-NEXT: entry: +; CHECK-NEXT: [[BASE1:%.*]] = freeze ptr [[BASE3:%.*]] +; CHECK-NEXT: [[BASE2:%.*]] = freeze ptr [[BASE4:%.*]] +; CHECK-NEXT: [[DEST:%.*]] = freeze ptr [[DEST2:%.*]] ; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_MEMCHECK:%.*]] ; CHECK: vector.memcheck: -; CHECK-NEXT: [[DEST1:%.*]] = ptrtoint ptr [[DEST:%.*]] to i64 +; CHECK-NEXT: [[DEST1:%.*]] = ptrtoint ptr [[DEST]] to i64 ; CHECK-NEXT: [[PREDS2:%.*]] = ptrtoint ptr [[PREDS:%.*]] to i64 -; CHECK-NEXT: [[BASE23:%.*]] = ptrtoint ptr [[BASE2:%.*]] to i64 -; CHECK-NEXT: [[BASE15:%.*]] = ptrtoint ptr [[BASE1:%.*]] to i64 +; CHECK-NEXT: [[BASE23:%.*]] = ptrtoint ptr [[BASE2]] to i64 +; CHECK-NEXT: [[BASE15:%.*]] = ptrtoint ptr [[BASE1]] to i64 ; CHECK-NEXT: [[TMP0:%.*]] = sub i64 [[DEST1]], [[PREDS2]] ; CHECK-NEXT: [[DIFF_CHECK:%.*]] = icmp ult i64 [[TMP0]], 16 ; CHECK-NEXT: [[TMP1:%.*]] = sub i64 [[DEST1]], [[BASE23]] -; CHECK-NEXT: [[DOTFR:%.*]] = freeze i64 [[TMP1]] -; CHECK-NEXT: [[DIFF_CHECK4:%.*]] = icmp ult i64 [[DOTFR]], 16 +; CHECK-NEXT: [[DIFF_CHECK4:%.*]] = icmp ult i64 [[TMP1]], 16 ; CHECK-NEXT: [[CONFLICT_RDX:%.*]] = or i1 [[DIFF_CHECK]], [[DIFF_CHECK4]] ; CHECK-NEXT: [[TMP2:%.*]] = sub i64 [[DEST1]], [[BASE15]] -; CHECK-NEXT: [[DOTFR10:%.*]] = freeze i64 [[TMP2]] -; CHECK-NEXT: [[DIFF_CHECK6:%.*]] = icmp ult i64 [[DOTFR10]], 16 +; CHECK-NEXT: [[DIFF_CHECK6:%.*]] = icmp ult i64 [[TMP2]], 16 ; CHECK-NEXT: [[CONFLICT_RDX7:%.*]] = or i1 [[CONFLICT_RDX]], [[DIFF_CHECK6]] ; CHECK-NEXT: br i1 [[CONFLICT_RDX7]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]] ; CHECK: vector.ph: diff --git a/llvm/test/Transforms/PGOProfile/chr.ll b/llvm/test/Transforms/PGOProfile/chr.ll index 46f9a2bde7a23..f0a1574c5f209 100644 --- a/llvm/test/Transforms/PGOProfile/chr.ll +++ b/llvm/test/Transforms/PGOProfile/chr.ll @@ -1295,6 +1295,7 @@ define i32 @test_chr_14(ptr %i, ptr %j, i32 %sum0, i1 %pred, i32 %z) !prof !14 { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[Z_FR:%.*]] = freeze i32 [[Z:%.*]] ; CHECK-NEXT: [[I0:%.*]] = load i32, ptr [[I:%.*]], align 4 +; CHECK-NEXT: [[I0_FR:%.*]] = freeze i32 [[I0]] ; CHECK-NEXT: [[V1_NOT:%.*]] = icmp eq i32 [[Z_FR]], 1 ; CHECK-NEXT: br i1 [[V1_NOT]], label [[BB1:%.*]], label [[ENTRY_SPLIT_NONCHR:%.*]], !prof [[PROF15]] ; CHECK: entry.split.nonchr: @@ -1307,27 +1308,26 @@ define i32 @test_chr_14(ptr %i, ptr %j, i32 %sum0, i1 %pred, i32 %z) !prof !14 { ; CHECK-NEXT: br label [[BB1]] ; CHECK: bb1: ; CHECK-NEXT: [[J0:%.*]] = load i32, ptr [[J:%.*]], align 4 -; CHECK-NEXT: [[V6:%.*]] = and i32 [[I0]], 2 -; CHECK-NEXT: [[V4:%.*]] = icmp ne i32 [[V6]], [[J0]] +; CHECK-NEXT: [[J0_FR:%.*]] = freeze i32 [[J0]] +; CHECK-NEXT: [[V6:%.*]] = and i32 [[I0_FR]], 2 +; CHECK-NEXT: [[TMP0:%.*]] = icmp ne i32 [[V6]], [[J0_FR]] ; CHECK-NEXT: [[V8:%.*]] = add i32 [[SUM0:%.*]], 43 -; CHECK-NEXT: [[V5:%.*]] = icmp ne i32 [[I0]], [[J0]] -; CHECK-NEXT: [[TMP0:%.*]] = freeze i1 [[V4]] -; CHECK-NEXT: [[TMP1:%.*]] = freeze i1 [[V5]] +; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i32 [[I0_FR]], [[J0_FR]] ; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP0]], [[TMP1]] ; CHECK-NEXT: br i1 [[TMP2]], label [[BB1_SPLIT:%.*]], label [[BB1_SPLIT_NONCHR:%.*]], !prof [[PROF15]] ; CHECK: bb1.split: ; CHECK-NEXT: call void @foo() -; CHECK-NEXT: [[V9:%.*]] = and i32 [[I0]], 4 +; CHECK-NEXT: [[V9:%.*]] = and i32 [[I0_FR]], 4 ; CHECK-NEXT: [[V10:%.*]] = icmp eq i32 [[V9]], 0 ; CHECK-NEXT: br i1 [[V10]], label [[BB3:%.*]], label [[BB2:%.*]] ; CHECK: bb2: ; CHECK-NEXT: call void @foo() ; CHECK-NEXT: br label [[BB3]] ; CHECK: bb1.split.nonchr: -; CHECK-NEXT: [[V5_NONCHR:%.*]] = icmp eq i32 [[I0]], [[J0]] +; CHECK-NEXT: [[V5_NONCHR:%.*]] = icmp eq i32 [[I0_FR]], [[J0_FR]] ; CHECK-NEXT: [[SUM3_NONCHR:%.*]] = select i1 [[V5_NONCHR]], i32 [[SUM0]], i32 [[V8]], !prof [[PROF16]] ; CHECK-NEXT: call void @foo() -; CHECK-NEXT: [[V9_NONCHR:%.*]] = and i32 [[I0]], 4 +; CHECK-NEXT: [[V9_NONCHR:%.*]] = and i32 [[I0_FR]], 4 ; CHECK-NEXT: [[V10_NONCHR:%.*]] = icmp eq i32 [[V9_NONCHR]], 0 ; CHECK-NEXT: br i1 [[V10_NONCHR]], label [[BB3]], label [[BB2_NONCHR:%.*]] ; CHECK: bb2.nonchr: @@ -1335,7 +1335,7 @@ define i32 @test_chr_14(ptr %i, ptr %j, i32 %sum0, i1 %pred, i32 %z) !prof !14 { ; CHECK-NEXT: br label [[BB3]] ; CHECK: bb3: ; CHECK-NEXT: [[TMP3:%.*]] = phi i32 [ [[V8]], [[BB2]] ], [ [[V8]], [[BB1_SPLIT]] ], [ [[SUM3_NONCHR]], [[BB2_NONCHR]] ], [ [[SUM3_NONCHR]], [[BB1_SPLIT_NONCHR]] ] -; CHECK-NEXT: [[V11:%.*]] = add i32 [[I0]], [[TMP3]] +; CHECK-NEXT: [[V11:%.*]] = add i32 [[I0_FR]], [[TMP3]] ; CHECK-NEXT: ret i32 [[V11]] ; entry: @@ -1932,12 +1932,12 @@ define i32 @test_chr_21(i64 %i, i64 %k, i64 %j) "instcombine-no-verify-fixpoint" ; CHECK-LABEL: @test_chr_21( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[I_FR:%.*]] = freeze i64 [[I:%.*]] -; CHECK-NEXT: [[CMP0:%.*]] = icmp ne i64 [[J:%.*]], [[K:%.*]] -; CHECK-NEXT: [[TMP0:%.*]] = freeze i1 [[CMP0]] +; CHECK-NEXT: [[J:%.*]] = freeze i64 [[J1:%.*]] +; CHECK-NEXT: [[K:%.*]] = freeze i64 [[K1:%.*]] +; CHECK-NEXT: [[CMP0:%.*]] = icmp ne i64 [[J]], [[K]] ; CHECK-NEXT: [[CMP3:%.*]] = icmp ne i64 [[J]], [[I_FR]] ; CHECK-NEXT: [[CMP_I:%.*]] = icmp ne i64 [[I_FR]], 86 -; CHECK-NEXT: [[TMP1:%.*]] = freeze i1 [[CMP3]] -; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP0]], [[TMP1]] +; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[CMP0]], [[CMP3]] ; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[CMP_I]] ; CHECK-NEXT: br i1 [[TMP3]], label [[BB1:%.*]], label [[ENTRY_SPLIT_NONCHR:%.*]], !prof [[PROF15]] ; CHECK: bb1: @@ -1963,7 +1963,7 @@ define i32 @test_chr_21(i64 %i, i64 %k, i64 %j) "instcombine-no-verify-fixpoint" ; CHECK-NEXT: call void @foo() ; CHECK-NEXT: br label [[BB10:%.*]] ; CHECK: entry.split.nonchr: -; CHECK-NEXT: br i1 [[TMP0]], label [[BB1_NONCHR:%.*]], label [[BB10]], !prof [[PROF18]] +; CHECK-NEXT: br i1 [[CMP0]], label [[BB1_NONCHR:%.*]], label [[BB10]], !prof [[PROF18]] ; CHECK: bb1.nonchr: ; CHECK-NEXT: [[CMP2_NONCHR:%.*]] = icmp eq i64 [[I_FR]], 2 ; CHECK-NEXT: br i1 [[CMP2_NONCHR]], label [[BB3_NONCHR:%.*]], label [[BB2_NONCHR:%.*]], !prof [[PROF16]] diff --git a/llvm/test/Transforms/PhaseOrdering/X86/vector-reductions-logical.ll b/llvm/test/Transforms/PhaseOrdering/X86/vector-reductions-logical.ll index ee51e467c5b8e..f6e5b0b29700b 100644 --- a/llvm/test/Transforms/PhaseOrdering/X86/vector-reductions-logical.ll +++ b/llvm/test/Transforms/PhaseOrdering/X86/vector-reductions-logical.ll @@ -86,11 +86,11 @@ return: define float @test_merge_anyof_v4sf(<4 x float> %t) { ; CHECK-LABEL: @test_merge_anyof_v4sf( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[TMP0:%.*]] = fcmp olt <4 x float> [[T:%.*]], zeroinitializer +; CHECK-NEXT: [[T:%.*]] = freeze <4 x float> [[T1:%.*]] +; CHECK-NEXT: [[TMP0:%.*]] = fcmp olt <4 x float> [[T]], zeroinitializer ; CHECK-NEXT: [[TMP1:%.*]] = fcmp ogt <4 x float> [[T]], splat (float 1.000000e+00) ; CHECK-NEXT: [[TMP3:%.*]] = shufflevector <4 x i1> [[TMP1]], <4 x i1> [[TMP0]], <8 x i32> -; CHECK-NEXT: [[TMP4:%.*]] = freeze <8 x i1> [[TMP3]] -; CHECK-NEXT: [[TMP5:%.*]] = bitcast <8 x i1> [[TMP4]] to i8 +; CHECK-NEXT: [[TMP5:%.*]] = bitcast <8 x i1> [[TMP3]] to i8 ; CHECK-NEXT: [[DOTNOT:%.*]] = icmp eq i8 [[TMP5]], 0 ; CHECK-NEXT: [[SHIFT:%.*]] = shufflevector <4 x float> [[T]], <4 x float> poison, <4 x i32> ; CHECK-NEXT: [[TMP6:%.*]] = fadd <4 x float> [[T]], [[SHIFT]] @@ -400,11 +400,11 @@ return: define float @test_merge_anyof_v4si(<4 x i32> %t) { ; CHECK-LABEL: @test_merge_anyof_v4si( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[TMP0:%.*]] = icmp slt <4 x i32> [[T:%.*]], splat (i32 1) +; CHECK-NEXT: [[T:%.*]] = freeze <4 x i32> [[T1:%.*]] +; CHECK-NEXT: [[TMP0:%.*]] = icmp slt <4 x i32> [[T]], splat (i32 1) ; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt <4 x i32> [[T]], splat (i32 255) ; CHECK-NEXT: [[TMP3:%.*]] = shufflevector <4 x i1> [[TMP1]], <4 x i1> [[TMP0]], <8 x i32> -; CHECK-NEXT: [[TMP4:%.*]] = freeze <8 x i1> [[TMP3]] -; CHECK-NEXT: [[TMP5:%.*]] = bitcast <8 x i1> [[TMP4]] to i8 +; CHECK-NEXT: [[TMP5:%.*]] = bitcast <8 x i1> [[TMP3]] to i8 ; CHECK-NEXT: [[DOTNOT:%.*]] = icmp eq i8 [[TMP5]], 0 ; CHECK-NEXT: [[SHIFT:%.*]] = shufflevector <4 x i32> [[T]], <4 x i32> poison, <4 x i32> ; CHECK-NEXT: [[TMP6:%.*]] = add nsw <4 x i32> [[T]], [[SHIFT]]