; RUN: llc -O2 < %s target datalayout = "E-m:e-p:32:32-i64:64-n32" target triple = "powerpc-unknown-linux-gnu" define void @test() { bb: br i1 undef, label %bb2, label %bb1 bb2: ; preds = %bb %i = select i1 undef, i64 0, i64 72057594037927936 store i64 %i, i64* undef, align 8 ret void bb1: ; preds = %bb %i50 = load i8, i8* undef, align 8 %i52 = load i128, i128* null, align 8 %i62 = icmp eq i8 %i50, 0 br i1 undef, label %bb66, label %bb64 bb64: ; preds = %bb63 ret void bb66: ; preds = %bb63 %i67 = lshr i128 -1, 0 %i68 = xor i128 %i52, -1 %i69 = add i128 0, %i68 %i70 = and i128 %i67, %i69 %i71 = icmp eq i128 %i70, 0 %i74 = select i1 %i62, i64 0, i64 72057594037927936 %i75 = select i1 %i71, i64 144115188075855872, i64 %i74 store i64 %i75, i64* undef, align 8 ret void } This enters an infinite combine loop inside PPCDAGToDAGISel::PeepholeCROps().
DAG: Optimized legalized selection DAG: %bb.4 'test:bb66' SelectionDAG has 30 nodes: t0: ch = EntryToken t4: i32,ch = CopyFromReg t0, Register:i32 %0 t20: i1,ch = CopyFromReg t0, Register:i1 %4 t6: i32,ch = CopyFromReg t4:1, Register:i32 %1 t8: i32,ch = CopyFromReg t6:1, Register:i32 %2 t10: i32,ch = CopyFromReg t8:1, Register:i32 %3 t37: i32 = and t10, t6 t38: i32 = and t8, t4 t39: i32 = and t37, t38 t41: i32 = select t20, Constant:i32<0>, OpaqueConstant:i32<16777216> t48: i32 = select_cc t39, Constant:i32<-1>, Constant:i32<33554432>, t41, seteq:ch t44: ch = store<(store 4 into `i64* undef`, align 8)> t0, t48, undef:i32, undef:i32 t29: i1 = setcc t39, Constant:i32<-1>, seteq:ch t49: i1 = or t29, t20 t50: i32 = select t49, Constant:i32<0>, OpaqueConstant:i32<0> t46: ch = store<(store 4 into `i64* undef` + 4, basealign 8)> t0, t50, undef:i32, undef:i32 t47: ch = TokenFactor t44, t46 t28: ch = PPCISD::RET_FLAG t47 Start of the peephole combine loop: ===== Instruction selection ends: Creating new machine node: t64: i1 = CRNOR t29, t20 CR Peephole replacing: Old: t50: i32 = SELECT_I4 t49, t34, t34 New: t50: i32 = SELECT_I4 t49, t34, t34 CR Peephole replacing: Old: t49: i1 = CROR t29, t20 New: t64: i1 = CRNOR t29, t20 CR Peephole replacing: Old: t50: i32 = SELECT_I4 t64, t34, t34 New: t50: i32 = SELECT_I4 t64, t34, t34 CR Peephole replacing: Old: t64: i1 = CRNOR t29, t20 New: t49: i1 = CROR t29, t20 Creating new machine node: t65: i1 = CRNOR t29, t20 CR Peephole replacing: Old: t50: i32 = SELECT_I4 t49, t34, t34 New: t50: i32 = SELECT_I4 t49, t34, t34 CR Peephole replacing: Old: t49: i1 = CROR t29, t20 New: t65: i1 = CRNOR t29, t20 CR Peephole replacing: Old: t50: i32 = SELECT_I4 t65, t34, t34 New: t50: i32 = SELECT_I4 t65, t34, t34 CR Peephole replacing: Old: t65: i1 = CRNOR t29, t20 New: t49: i1 = CROR t29, t20
Here's the DAG when entering PeepholeCROps: SelectionDAG has 38 nodes: t0: ch = EntryToken t34: i32 = LI TargetConstant:i32<0> t4: i32,ch = CopyFromReg t0, Register:i32 %0 t20: i1,ch = CopyFromReg t0, Register:i1 %4 t6: i32,ch = CopyFromReg t4:1, Register:i32 %1 t8: i32,ch = CopyFromReg t6:1, Register:i32 %2 t10: i32,ch = CopyFromReg t8:1, Register:i32 %3 t37: i32 = AND t10, t6 t38: i32 = AND t8, t4 t39: i32 = AND t37, t38 t60: i32 = TargetConstant<16777216> t62: i32 = TargetConstant<33554432> t58: i32 = CMPWI t39, TargetConstant:i32<65535> t31: i32 = LIS TargetConstant:i32<512> t35: i32 = LIS TargetConstant:i32<256> t41: i32 = SELECT_I4 t20, t34, t35 t48: i32 = SELECT_CC_I4 t58, t31, t41, TargetConstant:i32<76> t44: ch = STW<Mem:(store 4 into `i64* undef`, align 8)> t48, TargetConstant:i32<0>, IMPLICIT_DEF:i32, t0 t55: i32 = CMPWI t39, TargetConstant:i32<-1> t29: i1 = EXTRACT_SUBREG t55, TargetConstant:i32<3> t49: i1 = CROR t29, t20 t50: i32 = SELECT_I4 t49, t34, t34 t46: ch = STW<Mem:(store 4 into `i64* undef` + 4, basealign 8)> t50, TargetConstant:i32<0>, IMPLICIT_DEF:i32, t0 t47: ch = TokenFactor t44, t46 t28: ch = BLR t47 With the problematic part being: t34: i32 = LI TargetConstant:i32<0> t49: i1 = CROR t29, t20 t50: i32 = SELECT_I4 t49, t34, t34 The transform converts select x, y, y into select !x, y, y swapping the select operands, but of course that doesn't actually do anything if they're equal. And then we can convert that back to select x, y, y etc.
Candidate patch: https://reviews.llvm.org/D98340
Fixed by https://github.com/llvm/llvm-project/commit/2489cbaa8057c736475fd88990f4f6dbf022873d on main.
Merged: 8ca56905dd9b