1; Remove 'S' Scalar Dependencies #119345 2; Scalar dependencies are not handled correctly, so they were removed to avoid 3; miscompiles. The loop nest in this test case used to be interchanged, but it's 4; no longer triggering. XFAIL'ing this test to indicate that this test should 5; interchanged if scalar deps are handled correctly. 6; 7; XFAIL: * 8 9; RUN: opt < %s -passes=loop-interchange -verify-dom-info -verify-loop-info -pass-remarks-output=%t -disable-output 10; RUN: FileCheck -input-file %t %s 11 12@a = common global i32 0, align 4 13@d = common dso_local local_unnamed_addr global [1 x [6 x i32]] zeroinitializer, align 4 14 15; After interchanging the innermost and the middle loop, we should not continue 16; doing interchange for the (new) middle loop and the outermost loop, because of 17; values defined in the new innermost loop not available in the exiting block of 18; the entire loop nest. 19; 20; CHECK: --- !Passed 21; CHECK: Pass: loop-interchange 22; CHECK: Name: Interchanged 23; CHECK: Function: innermost_latch_uses_values_in_middle_header 24; CHECK: Args: 25; CHECK: - String: Loop interchanged with enclosing loop. 26; CHECK: ... 27; CHECK: --- !Missed 28; CHECK: Pass: loop-interchange 29; CHECK: Name: UnsupportedInnerLatchPHI 30; CHECK: Function: innermost_latch_uses_values_in_middle_header 31; CHECK: Args: 32; CHECK: - String: Cannot interchange loops because unsupported PHI nodes found in inner loop latch. 33; CHECK: ... 34; CHECK: --- !Missed 35; CHECK: Pass: loop-interchange 36; CHECK: Name: UnsupportedExitPHI 37; CHECK: Function: innermost_latch_uses_values_in_middle_header 38; CHECK: Args: 39; CHECK: - String: Found unsupported PHI node in loop exit. 40; CHECK: ... 41; 42define void @innermost_latch_uses_values_in_middle_header() { 43entry: 44 %0 = load i32, ptr @a, align 4 45 %b = add i32 80, 1 46 br label %outermost.header 47 48outermost.header: ; preds = %outermost.latch, %entry 49 %indvar.outermost = phi i32 [ 10, %entry ], [ %indvar.outermost.next, %outermost.latch ] 50 %tobool71.i = icmp eq i32 %0, 0 51 br i1 %tobool71.i, label %middle.header, label %outermost.latch 52 53middle.header: ; preds = %middle.latch, %outermost.header 54 %indvar.middle = phi i64 [ 4, %outermost.header ], [ %indvar.middle.next, %middle.latch ] 55 %indvar.middle.wide = zext i32 %b to i64 ; a def in the middle header 56 br label %innermost.header 57 58innermost.header: ; preds = %middle.header, %innermost.latch 59 %indvar.innermost = phi i64 [ %indvar.innermost.next, %innermost.latch ], [ 4, %middle.header ] 60 br label %innermost.body 61 62innermost.body: ; preds = %innermost.header 63 %arrayidx9.i = getelementptr inbounds [1 x [6 x i32]], ptr @d, i64 0, i64 %indvar.innermost, i64 %indvar.middle 64 store i32 0, ptr %arrayidx9.i, align 4 65 br label %innermost.latch 66 67innermost.latch: ; preds = %innermost.body 68 %indvar.innermost.next = add nsw i64 %indvar.innermost, 1 69 %tobool5.i = icmp eq i64 %indvar.innermost.next, %indvar.middle.wide ; corresponding use in the innermost latch 70 br i1 %tobool5.i, label %middle.latch, label %innermost.header 71 72middle.latch: ; preds = %innermost.latch 73 %indvar.middle.next = add nsw i64 %indvar.middle, -1 74 %tobool2.i = icmp eq i64 %indvar.middle.next, 0 75 br i1 %tobool2.i, label %outermost.latch, label %middle.header 76 77outermost.latch: ; preds = %middle.latch, %outermost.header 78 %indvar.outermost.next = add nsw i32 %indvar.outermost, -5 79 %tobool.i = icmp eq i32 %indvar.outermost.next, 0 80 br i1 %tobool.i, label %outermost.exit, label %outermost.header 81 82outermost.exit: ; preds = %outermost.latch 83 ret void 84} 85