Reland "Differentiate compiler synthesized ConstClass/CheckCast"
This reverts commit 10b104ffe3b77d3e289ac828ca8281da5d5c5e90.
Bug: 200933020
Change-Id: I8f7d19a042d67367ccd4c25502534e69af24b0dc
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfCheckCast.java b/src/main/java/com/android/tools/r8/cf/code/CfCheckCast.java
index 2220c7d..9e198e4 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfCheckCast.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfCheckCast.java
@@ -30,9 +30,19 @@
public class CfCheckCast extends CfInstruction implements CfTypeInstruction {
private final DexType type;
+ private final boolean ignoreCompatRules;
public CfCheckCast(DexType type) {
+ this(type, false);
+ }
+
+ public CfCheckCast(DexType type, boolean ignoreCompatRules) {
this.type = type;
+ this.ignoreCompatRules = ignoreCompatRules;
+ }
+
+ public boolean ignoreCompatRules() {
+ return ignoreCompatRules;
}
@Override
@@ -52,7 +62,7 @@
@Override
public CfInstruction withType(DexType newType) {
- return new CfCheckCast(newType);
+ return new CfCheckCast(newType, ignoreCompatRules());
}
@Override
@@ -88,7 +98,7 @@
@Override
void internalRegisterUse(
UseRegistry<?> registry, DexClassAndMethod context, ListIterator<CfInstruction> iterator) {
- registry.registerCheckCast(type);
+ registry.registerCheckCast(type, ignoreCompatRules());
}
@Override
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfConstClass.java b/src/main/java/com/android/tools/r8/cf/code/CfConstClass.java
index 78fbcd2..07cb6d2 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfConstClass.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfConstClass.java
@@ -30,9 +30,19 @@
public class CfConstClass extends CfInstruction implements CfTypeInstruction {
private final DexType type;
+ private final boolean ignoreCompatRules;
public CfConstClass(DexType type) {
+ this(type, false);
+ }
+
+ public CfConstClass(DexType type, boolean ignoreCompatRules) {
this.type = type;
+ this.ignoreCompatRules = ignoreCompatRules;
+ }
+
+ public boolean ignoreCompatRules() {
+ return ignoreCompatRules;
}
@Override
@@ -119,7 +129,7 @@
@Override
void internalRegisterUse(
UseRegistry<?> registry, DexClassAndMethod context, ListIterator<CfInstruction> iterator) {
- registry.registerConstClass(type, iterator);
+ registry.registerConstClass(type, iterator, ignoreCompatRules());
}
@Override
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfSafeCheckCast.java b/src/main/java/com/android/tools/r8/cf/code/CfSafeCheckCast.java
index 9fe64c6..f4e70ff 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfSafeCheckCast.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfSafeCheckCast.java
@@ -14,7 +14,7 @@
public class CfSafeCheckCast extends CfCheckCast {
public CfSafeCheckCast(DexType type) {
- super(type);
+ super(type, true);
}
@Override
diff --git a/src/main/java/com/android/tools/r8/code/CheckCast.java b/src/main/java/com/android/tools/r8/code/CheckCast.java
index cb21b8c..74a5f91 100644
--- a/src/main/java/com/android/tools/r8/code/CheckCast.java
+++ b/src/main/java/com/android/tools/r8/code/CheckCast.java
@@ -21,12 +21,16 @@
public static final String NAME = "CheckCast";
public static final String SMALI_NAME = "check-cast";
+ private final boolean ignoreCompatRules;
+
CheckCast(int high, BytecodeStream stream, OffsetToObjectMapping mapping) {
super(high, stream, mapping.getTypeMap());
+ this.ignoreCompatRules = false;
}
- public CheckCast(int valueRegister, DexType type) {
+ public CheckCast(int valueRegister, DexType type, boolean ignoreCompatRules) {
super(valueRegister, type);
+ this.ignoreCompatRules = ignoreCompatRules;
}
@Override
@@ -50,6 +54,11 @@
}
@Override
+ public boolean ignoreCompatRules() {
+ return ignoreCompatRules;
+ }
+
+ @Override
public void collectIndexedItems(
IndexedItemCollection indexedItems,
ProgramMethod context,
@@ -83,7 +92,7 @@
@Override
public void registerUse(UseRegistry<?> registry) {
- registry.registerCheckCast(getType());
+ registry.registerCheckCast(getType(), ignoreCompatRules());
}
public DexType getType() {
diff --git a/src/main/java/com/android/tools/r8/code/ConstClass.java b/src/main/java/com/android/tools/r8/code/ConstClass.java
index f57556a..88b35e1 100644
--- a/src/main/java/com/android/tools/r8/code/ConstClass.java
+++ b/src/main/java/com/android/tools/r8/code/ConstClass.java
@@ -21,12 +21,16 @@
public static final String NAME = "ConstClass";
public static final String SMALI_NAME = "const-class";
+ private final boolean ignoreCompatRules;
+
ConstClass(int high, BytecodeStream stream, OffsetToObjectMapping mapping) {
super(high, stream, mapping.getTypeMap());
+ this.ignoreCompatRules = false;
}
- public ConstClass(int dest, DexType type) {
+ public ConstClass(int dest, DexType type, boolean ignoreCompatRules) {
super(dest, type);
+ this.ignoreCompatRules = ignoreCompatRules;
}
@Override
@@ -35,6 +39,11 @@
}
@Override
+ public boolean ignoreCompatRules() {
+ return ignoreCompatRules;
+ }
+
+ @Override
public String getName() {
return NAME;
}
@@ -73,7 +82,7 @@
@Override
public void registerUse(UseRegistry<?> registry) {
- registry.registerConstClass(getType(), null);
+ registry.registerConstClass(getType(), null, ignoreCompatRules());
}
public DexType getType() {
diff --git a/src/main/java/com/android/tools/r8/code/Instruction.java b/src/main/java/com/android/tools/r8/code/Instruction.java
index 96e754e..5a10577 100644
--- a/src/main/java/com/android/tools/r8/code/Instruction.java
+++ b/src/main/java/com/android/tools/r8/code/Instruction.java
@@ -243,6 +243,10 @@
return 0;
}
+ public boolean ignoreCompatRules() {
+ return false;
+ }
+
static String formatOffset(int offset) {
return StringUtils.hexString(offset, 2);
}
diff --git a/src/main/java/com/android/tools/r8/code/SafeCheckCast.java b/src/main/java/com/android/tools/r8/code/SafeCheckCast.java
index 7fff773..8f19396 100644
--- a/src/main/java/com/android/tools/r8/code/SafeCheckCast.java
+++ b/src/main/java/com/android/tools/r8/code/SafeCheckCast.java
@@ -16,7 +16,7 @@
}
public SafeCheckCast(int valueRegister, DexType type) {
- super(valueRegister, type);
+ super(valueRegister, type, true);
}
@Override
diff --git a/src/main/java/com/android/tools/r8/graph/UseRegistry.java b/src/main/java/com/android/tools/r8/graph/UseRegistry.java
index 85241b8..c3912ca 100644
--- a/src/main/java/com/android/tools/r8/graph/UseRegistry.java
+++ b/src/main/java/com/android/tools/r8/graph/UseRegistry.java
@@ -121,16 +121,18 @@
}
public void registerConstClass(
- DexType type, ListIterator<? extends CfOrDexInstruction> iterator) {
+ DexType type,
+ ListIterator<? extends CfOrDexInstruction> iterator,
+ boolean ignoreCompatRules) {
registerTypeReference(type);
}
- public void registerCheckCast(DexType type) {
+ public void registerCheckCast(DexType type, boolean ignoreCompatRules) {
registerTypeReference(type);
}
public void registerSafeCheckCast(DexType type) {
- registerCheckCast(type);
+ registerCheckCast(type, true);
}
public void registerExceptionGuard(DexType guard) {
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/proto/ProtoEnqueuerUseRegistry.java b/src/main/java/com/android/tools/r8/ir/analysis/proto/ProtoEnqueuerUseRegistry.java
index 5a96b56..253665f 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/proto/ProtoEnqueuerUseRegistry.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/proto/ProtoEnqueuerUseRegistry.java
@@ -40,20 +40,23 @@
}
/**
- * Unlike {@link DefaultEnqueuerUseRegistry#registerConstClass(DexType, ListIterator)}, this
- * method does not trace any const-class instructions in every implementation of dynamicMethod().
+ * Unlike {@link DefaultEnqueuerUseRegistry#registerConstClass(DexType, ListIterator, boolean)},
+ * this method does not trace any const-class instructions in every implementation of
+ * dynamicMethod().
*
* <p>The const-class instructions that remain after the proto schema has been optimized will be
* traced manually by {@link ProtoEnqueuerExtension#tracePendingInstructionsInDynamicMethods}.
*/
@Override
public void registerConstClass(
- DexType type, ListIterator<? extends CfOrDexInstruction> iterator) {
+ DexType type,
+ ListIterator<? extends CfOrDexInstruction> iterator,
+ boolean ignoreCompatRules) {
if (references.isDynamicMethod(getContextMethod())) {
enqueuer.addDeadProtoTypeCandidate(type);
return;
}
- super.registerConstClass(type, iterator);
+ super.registerConstClass(type, iterator, ignoreCompatRules);
}
/**
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/proto/schema/ProtoEnqueuerExtension.java b/src/main/java/com/android/tools/r8/ir/analysis/proto/schema/ProtoEnqueuerExtension.java
index e7d953a..66747a7 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/proto/schema/ProtoEnqueuerExtension.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/proto/schema/ProtoEnqueuerExtension.java
@@ -497,7 +497,7 @@
object.asProtoObjectFromStaticGet().getField(), dynamicMethod);
} else if (object.isProtoTypeObject()) {
worklist.enqueueTraceConstClassAction(
- object.asProtoTypeObject().getType(), dynamicMethod);
+ object.asProtoTypeObject().getType(), dynamicMethod, false);
}
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/CheckCast.java b/src/main/java/com/android/tools/r8/ir/code/CheckCast.java
index b5e4027..764167c 100644
--- a/src/main/java/com/android/tools/r8/ir/code/CheckCast.java
+++ b/src/main/java/com/android/tools/r8/ir/code/CheckCast.java
@@ -30,14 +30,20 @@
public class CheckCast extends Instruction {
private final DexType type;
+ private final boolean ignoreCompatRules;
// A CheckCast dex instruction takes only one register containing a value and changes
// the associated type information for that value. In the IR we let the CheckCast
// instruction define a new value. During register allocation we then need to arrange it
// so that the source and destination are assigned the same register.
public CheckCast(Value dest, Value value, DexType type) {
+ this(dest, value, type, false);
+ }
+
+ public CheckCast(Value dest, Value value, DexType type, boolean ignoreCompatRules) {
super(dest, value);
this.type = type;
+ this.ignoreCompatRules = ignoreCompatRules;
}
public static Builder builder() {
@@ -66,6 +72,11 @@
}
@Override
+ public boolean ignoreCompatRules() {
+ return ignoreCompatRules;
+ }
+
+ @Override
public int opcode() {
return Opcodes.CHECK_CAST;
}
@@ -107,7 +118,7 @@
}
com.android.tools.r8.code.CheckCast createCheckCast(int register) {
- return new com.android.tools.r8.code.CheckCast(register, getType());
+ return new com.android.tools.r8.code.CheckCast(register, getType(), ignoreCompatRules());
}
@Override
diff --git a/src/main/java/com/android/tools/r8/ir/code/ConstClass.java b/src/main/java/com/android/tools/r8/ir/code/ConstClass.java
index 0fa4236..93cefd2 100644
--- a/src/main/java/com/android/tools/r8/ir/code/ConstClass.java
+++ b/src/main/java/com/android/tools/r8/ir/code/ConstClass.java
@@ -26,10 +26,16 @@
public class ConstClass extends ConstInstruction {
private final DexType clazz;
+ private final boolean ignoreCompatRules;
public ConstClass(Value dest, DexType clazz) {
+ this(dest, clazz, false);
+ }
+
+ public ConstClass(Value dest, DexType clazz, boolean ignoreCompatRules) {
super(dest);
this.clazz = clazz;
+ this.ignoreCompatRules = ignoreCompatRules;
}
public static Builder builder() {
@@ -72,7 +78,12 @@
@Override
public void buildDex(DexBuilder builder) {
int dest = builder.allocatedRegister(dest(), getNumber());
- builder.add(this, new com.android.tools.r8.code.ConstClass(dest, clazz));
+ builder.add(this, new com.android.tools.r8.code.ConstClass(dest, clazz, ignoreCompatRules()));
+ }
+
+ @Override
+ public boolean ignoreCompatRules() {
+ return ignoreCompatRules;
}
@Override
diff --git a/src/main/java/com/android/tools/r8/ir/code/Instruction.java b/src/main/java/com/android/tools/r8/ir/code/Instruction.java
index 85ac375..9bccbfc 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Instruction.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Instruction.java
@@ -120,6 +120,10 @@
}
}
+ public boolean ignoreCompatRules() {
+ return false;
+ }
+
public boolean hasInValueWithLocalInfo() {
return hasInValueThatMatches(Value::hasLocalInfo);
}
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/LensCodeRewriter.java b/src/main/java/com/android/tools/r8/ir/conversion/LensCodeRewriter.java
index d012cd6..c7b07d3 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/LensCodeRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/LensCodeRewriter.java
@@ -563,7 +563,9 @@
CheckCast checkCast = current.asCheckCast();
new InstructionReplacer(code, current, iterator, affectedPhis)
.replaceInstructionIfTypeChanged(
- checkCast.getType(), (t, v) -> new CheckCast(v, checkCast.object(), t));
+ checkCast.getType(),
+ (t, v) ->
+ new CheckCast(v, checkCast.object(), t, checkCast.ignoreCompatRules()));
}
break;
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/records/RecordDesugaring.java b/src/main/java/com/android/tools/r8/ir/desugar/records/RecordDesugaring.java
index 09319b6..0c1ee6e 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/records/RecordDesugaring.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/records/RecordDesugaring.java
@@ -391,7 +391,7 @@
assert recordInvokeDynamic.getRecordClass().lookupProgramMethod(getFieldsAsObjects) != null;
ArrayList<CfInstruction> instructions = new ArrayList<>();
instructions.add(new CfInvoke(Opcodes.INVOKESPECIAL, getFieldsAsObjects, false));
- instructions.add(new CfConstClass(recordInvokeDynamic.getRecordClass().type));
+ instructions.add(new CfConstClass(recordInvokeDynamic.getRecordClass().type, true));
instructions.add(new CfConstString(recordInvokeDynamic.getFieldNames()));
ProgramMethod programMethod =
synthesizeRecordHelper(
diff --git a/src/main/java/com/android/tools/r8/ir/synthetic/RecordCfCodeProvider.java b/src/main/java/com/android/tools/r8/ir/synthetic/RecordCfCodeProvider.java
index ce66391..e9fc30b 100644
--- a/src/main/java/com/android/tools/r8/ir/synthetic/RecordCfCodeProvider.java
+++ b/src/main/java/com/android/tools/r8/ir/synthetic/RecordCfCodeProvider.java
@@ -158,7 +158,7 @@
instructions.add(new CfLoad(recordType, 0));
instructions.add(new CfInvoke(Opcodes.INVOKESPECIAL, getFieldsAsObjects, false));
instructions.add(new CfLoad(objectType, 1));
- instructions.add(new CfCheckCast(getHolder()));
+ instructions.add(new CfCheckCast(getHolder(), true));
instructions.add(new CfInvoke(Opcodes.INVOKESPECIAL, getFieldsAsObjects, false));
instructions.add(
new CfInvoke(
diff --git a/src/main/java/com/android/tools/r8/shaking/DefaultEnqueuerUseRegistry.java b/src/main/java/com/android/tools/r8/shaking/DefaultEnqueuerUseRegistry.java
index 2287be5..33288f7 100644
--- a/src/main/java/com/android/tools/r8/shaking/DefaultEnqueuerUseRegistry.java
+++ b/src/main/java/com/android/tools/r8/shaking/DefaultEnqueuerUseRegistry.java
@@ -139,13 +139,15 @@
@Override
public void registerConstClass(
- DexType type, ListIterator<? extends CfOrDexInstruction> iterator) {
- enqueuer.traceConstClass(type, getContext(), iterator);
+ DexType type,
+ ListIterator<? extends CfOrDexInstruction> iterator,
+ boolean ignoreCompatRules) {
+ enqueuer.traceConstClass(type, getContext(), iterator, ignoreCompatRules);
}
@Override
- public void registerCheckCast(DexType type) {
- enqueuer.traceCheckCast(type, getContext());
+ public void registerCheckCast(DexType type, boolean ignoreCompatRules) {
+ enqueuer.traceCheckCast(type, getContext(), ignoreCompatRules);
}
@Override
diff --git a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
index b4fef63..ec6c061 100644
--- a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
+++ b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
@@ -1034,22 +1034,23 @@
}
}
- void traceCheckCast(DexType type, ProgramMethod currentMethod) {
+ void traceCheckCast(DexType type, ProgramMethod currentMethod, boolean ignoreCompatRules) {
checkCastAnalyses.forEach(analysis -> analysis.traceCheckCast(type, currentMethod));
- traceConstClassOrCheckCast(type, currentMethod);
+ internalTraceConstClassOrCheckCast(type, currentMethod, ignoreCompatRules);
}
void traceSafeCheckCast(DexType type, ProgramMethod currentMethod) {
checkCastAnalyses.forEach(analysis -> analysis.traceSafeCheckCast(type, currentMethod));
- traceCompilerSynthesizedConstClassOrCheckCast(type, currentMethod);
+ internalTraceConstClassOrCheckCast(type, currentMethod, true);
}
void traceConstClass(
DexType type,
ProgramMethod currentMethod,
- ListIterator<? extends CfOrDexInstruction> iterator) {
+ ListIterator<? extends CfOrDexInstruction> iterator,
+ boolean ignoreCompatRules) {
handleLockCandidate(type, currentMethod, iterator);
- traceConstClassOrCheckCast(type, currentMethod);
+ internalTraceConstClassOrCheckCast(type, currentMethod, ignoreCompatRules);
}
private void handleLockCandidate(
@@ -1103,22 +1104,10 @@
return result;
}
- private void traceConstClassOrCheckCast(DexType type, ProgramMethod currentMethod) {
- internalTraceConstClassOrCheckCast(type, currentMethod, false);
- }
-
- // TODO(b/190487539): Currently only used by traceSafeCheckCast(), but should also be used to
- // ensure we don't trigger compat behavior for const-class instructions synthesized for
- // synchronized methods.
- private void traceCompilerSynthesizedConstClassOrCheckCast(
- DexType type, ProgramMethod currentMethod) {
- internalTraceConstClassOrCheckCast(type, currentMethod, true);
- }
-
private void internalTraceConstClassOrCheckCast(
- DexType type, ProgramMethod currentMethod, boolean isCompilerSynthesized) {
+ DexType type, ProgramMethod currentMethod, boolean ignoreCompatRules) {
traceTypeReference(type, currentMethod);
- if (!forceProguardCompatibility || isCompilerSynthesized) {
+ if (!forceProguardCompatibility || ignoreCompatRules) {
return;
}
DexType baseType = type.toBaseType(appView.dexItemFactory());
diff --git a/src/main/java/com/android/tools/r8/shaking/EnqueuerWorklist.java b/src/main/java/com/android/tools/r8/shaking/EnqueuerWorklist.java
index ad3d4d1..1f4bc35 100644
--- a/src/main/java/com/android/tools/r8/shaking/EnqueuerWorklist.java
+++ b/src/main/java/com/android/tools/r8/shaking/EnqueuerWorklist.java
@@ -227,15 +227,17 @@
private final DexType type;
// TODO(b/175854431): Avoid pushing context on worklist.
private final ProgramMethod context;
+ private final boolean ignoreCompatRules;
- TraceConstClassAction(DexType type, ProgramMethod context) {
+ TraceConstClassAction(DexType type, ProgramMethod context, boolean ignoreCompatRules) {
this.type = type;
this.context = context;
+ this.ignoreCompatRules = ignoreCompatRules;
}
@Override
public void run(Enqueuer enqueuer) {
- enqueuer.traceConstClass(type, context, null);
+ enqueuer.traceConstClass(type, context, null, ignoreCompatRules);
}
}
@@ -356,7 +358,8 @@
public abstract void enqueueTraceCodeAction(ProgramMethod method);
- public abstract void enqueueTraceConstClassAction(DexType type, ProgramMethod context);
+ public abstract void enqueueTraceConstClassAction(
+ DexType type, ProgramMethod context, boolean ignoreCompatRules);
public abstract void enqueueTraceInvokeDirectAction(
DexMethod invokedMethod, ProgramMethod context);
@@ -464,8 +467,9 @@
}
@Override
- public void enqueueTraceConstClassAction(DexType type, ProgramMethod context) {
- queue.add(new TraceConstClassAction(type, context));
+ public void enqueueTraceConstClassAction(
+ DexType type, ProgramMethod context, boolean ignoreCompatRules) {
+ queue.add(new TraceConstClassAction(type, context, ignoreCompatRules));
}
@Override
@@ -580,26 +584,23 @@
}
@Override
- public void enqueueTraceConstClassAction(DexType type, ProgramMethod context) {
-
+ public void enqueueTraceConstClassAction(
+ DexType type, ProgramMethod context, boolean ignoreCompatRules) {
throw attemptToEnqueue();
}
@Override
public void enqueueTraceInvokeDirectAction(DexMethod invokedMethod, ProgramMethod context) {
-
throw attemptToEnqueue();
}
@Override
public void enqueueTraceNewInstanceAction(DexType type, ProgramMethod context) {
-
throw attemptToEnqueue();
}
@Override
public void enqueueTraceStaticFieldRead(DexField field, ProgramMethod context) {
-
throw attemptToEnqueue();
}
}
diff --git a/src/test/java/com/android/tools/r8/desugar/records/RecordShrinkFieldTest.java b/src/test/java/com/android/tools/r8/desugar/records/RecordShrinkFieldTest.java
index d46e947..7b653ed 100644
--- a/src/test/java/com/android/tools/r8/desugar/records/RecordShrinkFieldTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/records/RecordShrinkFieldTest.java
@@ -67,6 +67,22 @@
}
@Test
+ public void testR8Compat() throws Exception {
+ testForR8Compat(parameters.getBackend())
+ .addProgramClassFileData(PROGRAM_DATA)
+ .setMinApi(parameters.getApiLevel())
+ .addKeepMainRule(MAIN_TYPE)
+ .addKeepRules(
+ "-keepclassmembers,allowshrinking,allowoptimization class"
+ + " records.RecordShrinkField$Person { <fields>; }")
+ .addOptionsModification(TestingOptions::allowExperimentClassFileVersion)
+ .compile()
+ .inspect(this::assertSingleField)
+ .run(parameters.getRuntime(), MAIN_TYPE)
+ .assertSuccessWithOutput(EXPECTED_RESULT_R8);
+ }
+
+ @Test
public void testR8CfThenDex() throws Exception {
Path desugared =
testForR8(Backend.CF)