From fbe64f136f7650af22d90a77833eb42f8de1fbee Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sun, 18 Jul 2021 13:34:43 -0400 Subject: [PATCH] [SimplifyCFG] add test to show miscompile from FoldBranchToCommonDest (PR51125); NFC --- .../SimplifyCFG/fold-branch-to-common-dest.ll | 59 ++++++++++++++++++++-- 1 file changed, 55 insertions(+), 4 deletions(-) diff --git a/llvm/test/Transforms/SimplifyCFG/fold-branch-to-common-dest.ll b/llvm/test/Transforms/SimplifyCFG/fold-branch-to-common-dest.ll index 5f4226e..5ce7d60 100644 --- a/llvm/test/Transforms/SimplifyCFG/fold-branch-to-common-dest.ll +++ b/llvm/test/Transforms/SimplifyCFG/fold-branch-to-common-dest.ll @@ -121,10 +121,19 @@ final_right: ; FIXME: When we fold the dispatch block into pred, the call is moved to pred ; and the attribute nonnull is no longer valid on paramater. We should drop it. define void @one_pred_with_spec_call(i8 %v0, i8 %v1, i32* %p) { -; CHECK-LABEL: one_pred_with_spec_call -; CHECK-LABEL: pred: -; CHECK: %c0 = icmp ne i32* %p, null -; CHECK: %x = call i32 @speculate_call(i32* nonnull %p) +; CHECK-LABEL: @one_pred_with_spec_call( +; CHECK-NEXT: pred: +; CHECK-NEXT: [[C0:%.*]] = icmp ne i32* [[P:%.*]], null +; CHECK-NEXT: [[X:%.*]] = call i32 @speculate_call(i32* nonnull [[P]]) +; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[V1:%.*]], 0 +; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[C0]], i1 [[C1]], i1 false +; CHECK-NEXT: br i1 [[OR_COND]], label [[COMMON_RET:%.*]], label [[FINAL_RIGHT:%.*]] +; CHECK: common.ret: +; CHECK-NEXT: ret void +; CHECK: final_right: +; CHECK-NEXT: call void @sideeffect0() +; CHECK-NEXT: br label [[COMMON_RET]] +; pred: %c0 = icmp ne i32* %p, null br i1 %c0, label %dispatch, label %final_right @@ -988,4 +997,46 @@ for.end: ret void } +; FIXME: +; This is a miscompile if we replace a phi incoming value +; with an updated loaded value *after* it was stored. + +@global_pr51125 = global i32 1, align 4 + +define i32 @pr51125() { +; CHECK-LABEL: @pr51125( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[LD_OLD:%.*]] = load i32, i32* @global_pr51125, align 4 +; CHECK-NEXT: [[ISZERO_OLD:%.*]] = icmp eq i32 [[LD_OLD]], 0 +; CHECK-NEXT: br i1 [[ISZERO_OLD]], label [[EXIT:%.*]], label [[L2:%.*]] +; CHECK: L2: +; CHECK-NEXT: [[LD_MERGE:%.*]] = phi i32 [ [[LD:%.*]], [[L2]] ], [ [[LD_OLD]], [[ENTRY:%.*]] ] +; CHECK-NEXT: store i32 -1, i32* @global_pr51125, align 4 +; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[LD_MERGE]], -1 +; CHECK-NEXT: [[LD]] = load i32, i32* @global_pr51125, align 4 +; CHECK-NEXT: [[ISZERO:%.*]] = icmp eq i32 [[LD]], 0 +; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[CMP]], i1 true, i1 [[ISZERO]] +; CHECK-NEXT: br i1 [[OR_COND]], label [[EXIT]], label [[L2]] +; CHECK: exit: +; CHECK-NEXT: [[R:%.*]] = phi i32 [ [[LD]], [[L2]] ], [ [[LD_OLD]], [[ENTRY]] ] +; CHECK-NEXT: ret i32 [[R]] +; +entry: + br label %L + +L: + %ld = load i32, i32* @global_pr51125, align 4 + %iszero = icmp eq i32 %ld, 0 + br i1 %iszero, label %exit, label %L2 + +L2: + store i32 -1, i32* @global_pr51125, align 4 + %cmp = icmp eq i32 %ld, -1 + br i1 %cmp, label %L, label %exit + +exit: + %r = phi i32 [ %ld, %L2 ], [ %ld, %L ] + ret i32 %r +} + attributes #0 = { nounwind argmemonly speculatable } -- 2.7.4