From 06fb4e90649f264a129d3ad2a08fd3492ee78651 Mon Sep 17 00:00:00 2001 From: David Green Date: Mon, 14 Sep 2020 12:08:34 +0100 Subject: [PATCH] [CGP] Limit converting phi types to simple loads and stores Instcombine limits converting phi types to simple loads and stores. This does the same in codegenprepare, not processing phis that are not simple. Note that volatile loads/store ISel will happily convert between float and int. Atomics are more likely to always be integer. This just keeps things simple and doesn't process either. Differential Revision: https://reviews.llvm.org/D83770 --- llvm/lib/CodeGen/CodeGenPrepare.cpp | 4 +- llvm/test/CodeGen/AArch64/convertphitype.ll | 200 ++++++++++++++++++++++++++++ 2 files changed, 203 insertions(+), 1 deletion(-) diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp index bb0bad7..45feeae 100644 --- a/llvm/lib/CodeGen/CodeGenPrepare.cpp +++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp @@ -5831,6 +5831,8 @@ bool CodeGenPrepare::optimizePhiType( Worklist.push_back(OpPhi); } } else if (auto *OpLoad = dyn_cast(V)) { + if (!OpLoad->isSimple()) + return false; if (!Defs.count(OpLoad)) { Defs.insert(OpLoad); Worklist.push_back(OpLoad); @@ -5868,7 +5870,7 @@ bool CodeGenPrepare::optimizePhiType( Worklist.push_back(OpPhi); } } else if (auto *OpStore = dyn_cast(V)) { - if (OpStore->getOperand(0) != II) + if (!OpStore->isSimple() || OpStore->getOperand(0) != II) return false; Uses.insert(OpStore); } else if (auto *OpBC = dyn_cast(V)) { diff --git a/llvm/test/CodeGen/AArch64/convertphitype.ll b/llvm/test/CodeGen/AArch64/convertphitype.ll index 2e3530d..bc858aa 100644 --- a/llvm/test/CodeGen/AArch64/convertphitype.ll +++ b/llvm/test/CodeGen/AArch64/convertphitype.ll @@ -677,3 +677,203 @@ end: %b = bitcast i32 %phi to float ret float %b } + +define float @convphi_volatile(i32 *%s, i32 *%d, i32 %n) { +; CHECK-LABEL: @convphi_volatile( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CMP15:%.*]] = icmp sgt i32 [[N:%.*]], 0 +; CHECK-NEXT: br i1 [[CMP15]], label [[THEN:%.*]], label [[ELSE:%.*]] +; CHECK: then: +; CHECK-NEXT: [[LS:%.*]] = load volatile i32, i32* [[S:%.*]], align 4 +; CHECK-NEXT: br label [[END:%.*]] +; CHECK: else: +; CHECK-NEXT: [[LD:%.*]] = load i32, i32* [[D:%.*]], align 4 +; CHECK-NEXT: br label [[END]] +; CHECK: end: +; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ [[LS]], [[THEN]] ], [ [[LD]], [[ELSE]] ] +; CHECK-NEXT: [[B:%.*]] = bitcast i32 [[PHI]] to float +; CHECK-NEXT: ret float [[B]] +; +; DEBUG-LABEL: @convphi_volatile( +; DEBUG-NEXT: entry: +; DEBUG-NEXT: [[CMP15:%.*]] = icmp sgt i32 [[N:%.*]], 0, !dbg !358 +; DEBUG-NEXT: call void @llvm.dbg.value(metadata i1 [[CMP15]], metadata !353, metadata !DIExpression()), !dbg !358 +; DEBUG-NEXT: br i1 [[CMP15]], label [[THEN:%.*]], label [[ELSE:%.*]], !dbg !359 +; DEBUG: then: +; DEBUG-NEXT: [[LS:%.*]] = load volatile i32, i32* [[S:%.*]], align 4, !dbg !360 +; DEBUG-NEXT: call void @llvm.dbg.value(metadata i32 [[LS]], metadata !354, metadata !DIExpression()), !dbg !360 +; DEBUG-NEXT: br label [[END:%.*]], !dbg !361 +; DEBUG: else: +; DEBUG-NEXT: [[LD:%.*]] = load i32, i32* [[D:%.*]], align 4, !dbg !362 +; DEBUG-NEXT: call void @llvm.dbg.value(metadata i32 [[LD]], metadata !355, metadata !DIExpression()), !dbg !362 +; DEBUG-NEXT: br label [[END]], !dbg !363 +; DEBUG: end: +; DEBUG-NEXT: [[PHI:%.*]] = phi i32 [ [[LS]], [[THEN]] ], [ [[LD]], [[ELSE]] ], !dbg !364 +; DEBUG-NEXT: call void @llvm.dbg.value(metadata i32 [[PHI]], metadata !356, metadata !DIExpression()), !dbg !364 +; DEBUG-NEXT: [[B:%.*]] = bitcast i32 [[PHI]] to float, !dbg !365 +; DEBUG-NEXT: call void @llvm.dbg.value(metadata float [[B]], metadata !357, metadata !DIExpression()), !dbg !365 +; DEBUG-NEXT: ret float [[B]], !dbg !366 +; +entry: + %cmp15 = icmp sgt i32 %n, 0 + br i1 %cmp15, label %then, label %else + +then: + %ls = load volatile i32, i32* %s, align 4 + br label %end + +else: + %ld = load i32, i32* %d, align 4 + br label %end + +end: + %phi = phi i32 [ %ls, %then ], [ %ld, %else ] + %b = bitcast i32 %phi to float + ret float %b +} + +define void @convphi_volatile2(i32 *%s, i32 *%d, i32 %n, float %f) { +; CHECK-LABEL: @convphi_volatile2( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CMP15:%.*]] = icmp sgt i32 [[N:%.*]], 0 +; CHECK-NEXT: [[FB:%.*]] = bitcast float [[F:%.*]] to i32 +; CHECK-NEXT: br i1 [[CMP15]], label [[THEN:%.*]], label [[END:%.*]] +; CHECK: then: +; CHECK-NEXT: [[LS:%.*]] = load i32, i32* [[S:%.*]], align 4 +; CHECK-NEXT: br label [[END]] +; CHECK: end: +; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ [[LS]], [[THEN]] ], [ [[FB]], [[ENTRY:%.*]] ] +; CHECK-NEXT: store volatile i32 [[PHI]], i32* [[D:%.*]], align 4 +; CHECK-NEXT: ret void +; +; DEBUG-LABEL: @convphi_volatile2( +; DEBUG-NEXT: entry: +; DEBUG-NEXT: [[CMP15:%.*]] = icmp sgt i32 [[N:%.*]], 0, !dbg !373 +; DEBUG-NEXT: call void @llvm.dbg.value(metadata i1 [[CMP15]], metadata !369, metadata !DIExpression()), !dbg !373 +; DEBUG-NEXT: [[FB:%.*]] = bitcast float [[F:%.*]] to i32, !dbg !374 +; DEBUG-NEXT: call void @llvm.dbg.value(metadata i32 [[FB]], metadata !370, metadata !DIExpression()), !dbg !374 +; DEBUG-NEXT: br i1 [[CMP15]], label [[THEN:%.*]], label [[END:%.*]], !dbg !375 +; DEBUG: then: +; DEBUG-NEXT: [[LS:%.*]] = load i32, i32* [[S:%.*]], align 4, !dbg !376 +; DEBUG-NEXT: call void @llvm.dbg.value(metadata i32 [[LS]], metadata !371, metadata !DIExpression()), !dbg !376 +; DEBUG-NEXT: br label [[END]], !dbg !377 +; DEBUG: end: +; DEBUG-NEXT: [[PHI:%.*]] = phi i32 [ [[LS]], [[THEN]] ], [ [[FB]], [[ENTRY:%.*]] ], !dbg !378 +; DEBUG-NEXT: call void @llvm.dbg.value(metadata i32 [[PHI]], metadata !372, metadata !DIExpression()), !dbg !378 +; DEBUG-NEXT: store volatile i32 [[PHI]], i32* [[D:%.*]], align 4, !dbg !379 +; DEBUG-NEXT: ret void, !dbg !380 +; +entry: + %cmp15 = icmp sgt i32 %n, 0 + %fb = bitcast float %f to i32 + br i1 %cmp15, label %then, label %end + +then: + %ls = load i32, i32* %s, align 4 + br label %end + +end: + %phi = phi i32 [ %ls, %then ], [ %fb, %entry ] + store volatile i32 %phi, i32 *%d + ret void +} + +define float @convphi_atomic(i32 *%s, i32 *%d, i32 %n) { +; CHECK-LABEL: @convphi_atomic( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CMP15:%.*]] = icmp sgt i32 [[N:%.*]], 0 +; CHECK-NEXT: br i1 [[CMP15]], label [[THEN:%.*]], label [[ELSE:%.*]] +; CHECK: then: +; CHECK-NEXT: [[LS:%.*]] = load atomic i32, i32* [[S:%.*]] acquire, align 4 +; CHECK-NEXT: br label [[END:%.*]] +; CHECK: else: +; CHECK-NEXT: [[LD:%.*]] = load i32, i32* [[D:%.*]], align 4 +; CHECK-NEXT: br label [[END]] +; CHECK: end: +; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ [[LS]], [[THEN]] ], [ [[LD]], [[ELSE]] ] +; CHECK-NEXT: [[B:%.*]] = bitcast i32 [[PHI]] to float +; CHECK-NEXT: ret float [[B]] +; +; DEBUG-LABEL: @convphi_atomic( +; DEBUG-NEXT: entry: +; DEBUG-NEXT: [[CMP15:%.*]] = icmp sgt i32 [[N:%.*]], 0, !dbg !388 +; DEBUG-NEXT: call void @llvm.dbg.value(metadata i1 [[CMP15]], metadata !383, metadata !DIExpression()), !dbg !388 +; DEBUG-NEXT: br i1 [[CMP15]], label [[THEN:%.*]], label [[ELSE:%.*]], !dbg !389 +; DEBUG: then: +; DEBUG-NEXT: [[LS:%.*]] = load atomic i32, i32* [[S:%.*]] acquire, align 4, !dbg !390 +; DEBUG-NEXT: call void @llvm.dbg.value(metadata i32 [[LS]], metadata !384, metadata !DIExpression()), !dbg !390 +; DEBUG-NEXT: br label [[END:%.*]], !dbg !391 +; DEBUG: else: +; DEBUG-NEXT: [[LD:%.*]] = load i32, i32* [[D:%.*]], align 4, !dbg !392 +; DEBUG-NEXT: call void @llvm.dbg.value(metadata i32 [[LD]], metadata !385, metadata !DIExpression()), !dbg !392 +; DEBUG-NEXT: br label [[END]], !dbg !393 +; DEBUG: end: +; DEBUG-NEXT: [[PHI:%.*]] = phi i32 [ [[LS]], [[THEN]] ], [ [[LD]], [[ELSE]] ], !dbg !394 +; DEBUG-NEXT: call void @llvm.dbg.value(metadata i32 [[PHI]], metadata !386, metadata !DIExpression()), !dbg !394 +; DEBUG-NEXT: [[B:%.*]] = bitcast i32 [[PHI]] to float, !dbg !395 +; DEBUG-NEXT: call void @llvm.dbg.value(metadata float [[B]], metadata !387, metadata !DIExpression()), !dbg !395 +; DEBUG-NEXT: ret float [[B]], !dbg !396 +; +entry: + %cmp15 = icmp sgt i32 %n, 0 + br i1 %cmp15, label %then, label %else + +then: + %ls = load atomic i32, i32* %s acquire, align 4 + br label %end + +else: + %ld = load i32, i32* %d, align 4 + br label %end + +end: + %phi = phi i32 [ %ls, %then ], [ %ld, %else ] + %b = bitcast i32 %phi to float + ret float %b +} + +define void @convphi_atomic2(i32 *%s, i32 *%d, i32 %n, float %f) { +; CHECK-LABEL: @convphi_atomic2( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CMP15:%.*]] = icmp sgt i32 [[N:%.*]], 0 +; CHECK-NEXT: [[FB:%.*]] = bitcast float [[F:%.*]] to i32 +; CHECK-NEXT: br i1 [[CMP15]], label [[THEN:%.*]], label [[END:%.*]] +; CHECK: then: +; CHECK-NEXT: [[LS:%.*]] = load i32, i32* [[S:%.*]], align 4 +; CHECK-NEXT: br label [[END]] +; CHECK: end: +; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ [[LS]], [[THEN]] ], [ [[FB]], [[ENTRY:%.*]] ] +; CHECK-NEXT: store atomic i32 [[PHI]], i32* [[D:%.*]] release, align 4 +; CHECK-NEXT: ret void +; +; DEBUG-LABEL: @convphi_atomic2( +; DEBUG-NEXT: entry: +; DEBUG-NEXT: [[CMP15:%.*]] = icmp sgt i32 [[N:%.*]], 0, !dbg !403 +; DEBUG-NEXT: call void @llvm.dbg.value(metadata i1 [[CMP15]], metadata !399, metadata !DIExpression()), !dbg !403 +; DEBUG-NEXT: [[FB:%.*]] = bitcast float [[F:%.*]] to i32, !dbg !404 +; DEBUG-NEXT: call void @llvm.dbg.value(metadata i32 [[FB]], metadata !400, metadata !DIExpression()), !dbg !404 +; DEBUG-NEXT: br i1 [[CMP15]], label [[THEN:%.*]], label [[END:%.*]], !dbg !405 +; DEBUG: then: +; DEBUG-NEXT: [[LS:%.*]] = load i32, i32* [[S:%.*]], align 4, !dbg !406 +; DEBUG-NEXT: call void @llvm.dbg.value(metadata i32 [[LS]], metadata !401, metadata !DIExpression()), !dbg !406 +; DEBUG-NEXT: br label [[END]], !dbg !407 +; DEBUG: end: +; DEBUG-NEXT: [[PHI:%.*]] = phi i32 [ [[LS]], [[THEN]] ], [ [[FB]], [[ENTRY:%.*]] ], !dbg !408 +; DEBUG-NEXT: call void @llvm.dbg.value(metadata i32 [[PHI]], metadata !402, metadata !DIExpression()), !dbg !408 +; DEBUG-NEXT: store atomic i32 [[PHI]], i32* [[D:%.*]] release, align 4, !dbg !409 +; DEBUG-NEXT: ret void, !dbg !410 +; +entry: + %cmp15 = icmp sgt i32 %n, 0 + %fb = bitcast float %f to i32 + br i1 %cmp15, label %then, label %end + +then: + %ls = load i32, i32* %s, align 4 + br label %end + +end: + %phi = phi i32 [ %ls, %then ], [ %fb, %entry ] + store atomic i32 %phi, i32 *%d release, align 4 + ret void +} -- 2.7.4